summaryrefslogtreecommitdiff
path: root/p/haskell-clientsession
diff options
context:
space:
mode:
authorclint <clint@debian.org>2011-09-10 17:22:17 +0400
committerclint <clint@debian.org>2011-09-10 17:22:17 +0400
commit30d4d533d93d7280fb8a08a450fe5ac03f922182 (patch)
treea28a755849ef6fefcad37b543c421ac5b8011426 /p/haskell-clientsession
parente22573f27fa62b106a7d9f72c713e3afb41170a5 (diff)
downloadDHG_packages-30d4d533d93d7280fb8a08a450fe5ac03f922182.tar.gz
haskell-clientsession: New upstream version 0.7.0.
Diffstat (limited to 'p/haskell-clientsession')
-rw-r--r--p/haskell-clientsession/debian/changelog6
-rw-r--r--p/haskell-clientsession/debian/control20
-rw-r--r--p/haskell-clientsession/debian/patches/debian-changes-0.7.0-1223
-rw-r--r--p/haskell-clientsession/debian/patches/series1
4 files changed, 250 insertions, 0 deletions
diff --git a/p/haskell-clientsession/debian/changelog b/p/haskell-clientsession/debian/changelog
index a7b0030ee..7a5b35be0 100644
--- a/p/haskell-clientsession/debian/changelog
+++ b/p/haskell-clientsession/debian/changelog
@@ -1,3 +1,9 @@
+haskell-clientsession (0.7.0-1) unstable; urgency=low
+
+ * New upstream version.
+
+ -- Clint Adams <clint@debian.org> Sat, 10 Sep 2011 08:58:53 -0400
+
haskell-clientsession (0.6.0-1) unstable; urgency=low
* New upstream release.
diff --git a/p/haskell-clientsession/debian/control b/p/haskell-clientsession/debian/control
index 3612918b3..5e7aa6a78 100644
--- a/p/haskell-clientsession/debian/control
+++ b/p/haskell-clientsession/debian/control
@@ -9,7 +9,27 @@ Build-Depends: debhelper (>= 7)
, ghc
, ghc-prof
, ghc-ghci
+ , libghc-base64-bytestring-dev (>> 0.1.0.3)
+ , libghc-base64-bytestring-dev (<< 0.2)
+ , libghc-base64-bytestring-prof
+ , libghc-cereal-dev (>> 0.3)
+ , libghc-cereal-dev (<< 0.4)
+ , libghc-cereal-prof
+ , libghc-crypto-api-dev (>> 0.6.4)
+ , libghc-crypto-api-dev (<< 0.7)
+ , libghc-crypto-api-prof
+ , libghc-cryptocipher-dev (>> 0.2.5)
+ , libghc-cryptocipher-dev (<< 0.3)
+ , libghc-cryptocipher-prof
+ , libghc-cryptohash-dev (>> 0.7.1)
+ , libghc-cryptohash-dev (<< 0.8)
+ , libghc-cryptohash-prof
Build-Depends-Indep: ghc-doc
+ , libghc-base64-bytestring-doc
+ , libghc-cereal-doc
+ , libghc-crypto-api-doc
+ , libghc-cryptocipher-doc
+ , libghc-cryptohash-doc
Standards-Version: 3.9.2
Homepage: http://hackage.haskell.org/package/clientsession
Vcs-Darcs: http://darcs.debian.org/pkg-haskell/haskell-clientsession
diff --git a/p/haskell-clientsession/debian/patches/debian-changes-0.7.0-1 b/p/haskell-clientsession/debian/patches/debian-changes-0.7.0-1
new file mode 100644
index 000000000..71a5211cf
--- /dev/null
+++ b/p/haskell-clientsession/debian/patches/debian-changes-0.7.0-1
@@ -0,0 +1,223 @@
+Description: Upstream changes introduced in version 0.7.0-1
+ This patch has been created by dpkg-source during the package build.
+ Here's the last changelog entry, hopefully it gives details on why
+ those changes were made:
+ .
+ haskell-clientsession (0.7.0-1) unstable; urgency=low
+ .
+ * New upstream version.
+ .
+ The person named in the Author field signed this changelog entry.
+Author: Clint Adams <clint@debian.org>
+
+---
+The information above should follow the Patch Tagging Guidelines, please
+checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
+are templates for supplementary fields that you might want to add:
+
+Origin: <vendor|upstream|other>, <url of original patch>
+Bug: <url in upstream bugtracker>
+Bug-Debian: http://bugs.debian.org/<bugnumber>
+Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
+Forwarded: <no|not-needed|url proving that it has been forwarded>
+Reviewed-By: <name and email of someone who approved the patch>
+Last-Update: <YYYY-MM-DD>
+
+--- /dev/null
++++ haskell-clientsession-0.7.0/src/Web/ClientSession.hs
+@@ -0,0 +1,195 @@
++{-# LANGUAGE FlexibleContexts #-}
++{-# LANGUAGE ForeignFunctionInterface #-}
++{-# LANGUAGE TemplateHaskell #-}
++---------------------------------------------------------
++--
++-- |
++--
++-- Module : Web.ClientSession
++-- Copyright : Michael Snoyman
++-- License : BSD3
++--
++-- Maintainer : Michael Snoyman <michael@snoyman.com>
++-- Stability : Stable
++-- Portability : portable
++--
++-- Stores session data in a client cookie. In order to do so,
++-- we:
++--
++-- * Encrypt the cookie data using AES in CBC mode. This allows
++-- you to store sensitive information on the client side without
++-- worrying about eavesdropping.
++--
++-- * Sign the encrypted cookie data using HMAC-SHA256. Besides
++-- detecting potential errors in storage or transmission of the
++-- cookies (integrity), the HMAC-SHA256 code also avoids
++-- malicious modifications of the cookie data by assuring you
++-- that the cookie data really was generated by this server
++-- (authentication).
++--
++-- * Encode everything using Base64. Thus we avoid problems with
++-- non-printable characters by giving the browser a simple
++-- string.
++--
++-- Simple usage of the library involves just calling
++-- 'getDefaultKey' on the startup of your server, 'encryptIO'
++-- when serializing cookies and 'decrypt' when parsing then back.
++--
++---------------------------------------------------------
++module Web.ClientSession
++ ( -- * Automatic key generation
++ Key(..)
++ , IV
++ , randomIV
++ , mkIV
++ , getKey
++ , defaultKeyFile
++ , getDefaultKey
++ , initKey
++ -- * Actual encryption/decryption
++ , encrypt
++ , encryptIO
++ , decrypt
++ ) where
++
++import Control.Arrow (second)
++import Control.Monad (guard)
++import Data.Bits (xor)
++import System.Directory (doesFileExist)
++import qualified Data.ByteString as S
++import qualified Crypto.Cipher.AES as A
++import Crypto.Hash.SHA256 (SHA256)
++import Crypto.HMAC (MacKey(..), hmac')
++import qualified Data.ByteString.Base64 as B
++import Crypto.Random (newGenIO, genBytes, SystemRandom)
++import Data.Serialize (encode)
++
++-- | The keys used to store the cookies. We have an AES key used
++-- to encrypt the cookie and a HMAC-SHA256 key used verify the
++-- authencity and integrity of the cookie. The AES key needs to
++-- have exactly 32 bytes (256 bits). The HMAC-SHA256 should have
++-- 64 bytes (512 bits), which is the block size of SHA256, but
++-- any size may be used.
++--
++-- See also 'getDefaultKey' and 'initKey'.
++data Key = Key { aesKey :: A.Key
++ , hmacKey :: MacKey }
++ deriving (Eq, Show)
++
++-- | The initialization vector used by AES in CBC mode. Should
++-- be exactly 16 bytes long.
++newtype IV = IV S.ByteString
++ deriving Show
++
++-- | Construct an initialization vector from a 'S.ByteString'.
++-- Fails if there isn't exactly 16 bytes.
++mkIV :: S.ByteString -> Maybe IV
++mkIV bs
++ | S.length bs == 16 = Just $ IV bs
++ | otherwise = Nothing
++
++-- | Randomly construct a fresh initialization vector. You
++-- /should not/ reuse initialization vectors.
++randomIV :: IO IV
++randomIV = fmap IV $ randomBytes 16
++
++-- | The default key file.
++defaultKeyFile :: FilePath
++defaultKeyFile = "client_session_key.aes"
++
++-- | Simply calls 'getKey' 'defaultKeyFile'.
++getDefaultKey :: IO Key
++getDefaultKey = getKey defaultKeyFile
++
++-- | Get a key from the given text file.
++--
++-- If the file does not exist or is corrupted a random key will
++-- be generated and stored in that file.
++getKey :: FilePath -- ^ File name where key is stored.
++ -> IO Key -- ^ The actual key.
++getKey keyFile = do
++ exists <- doesFileExist keyFile
++ if exists
++ then S.readFile keyFile >>= either (const newKey) return . initKey
++ else newKey
++ where
++ newKey = do
++ (bs, key') <- randomKey
++ S.writeFile keyFile bs
++ return key'
++
++-- | Generate the given number of random bytes.
++randomBytes :: Int -> IO S.ByteString
++randomBytes len = do
++ g <- newGenIO
++ either (error . show) (return . fst) $ genBytes len (g :: SystemRandom)
++
++-- | Generate a random 'Key'. Besides the 'Key', the
++-- 'ByteString' passed to 'initKey' is returned so that it can be
++-- saved for later use.
++randomKey :: IO (S.ByteString, Key)
++randomKey = do
++ bs <- randomBytes 64
++ case initKey bs of
++ Left e -> error $ "Web.ClientSession.randomKey: never here, " ++ e
++ Right key -> return (bs, key)
++
++-- | Initializes a 'Key' from a random 'S.ByteString'. It's
++-- better to give a 'S.ByteString' with exactly 64 bytes, but
++-- anything with at least 32 bytes will work.
++initKey :: S.ByteString -> Either String Key
++initKey bs | S.length bs < 32 = Left $ "Web.ClientSession.initKey: length of " ++
++ show (S.length bs) ++ " too small."
++initKey bs = fmap mk $ A.initKey256 preAesKey
++ where
++ preAesKey | S.length bs >= 64 = S.pack $ uncurry (S.zipWith xor) $ S.splitAt 32 bs
++ | otherwise = S.take 32 bs
++ mk k = Key { aesKey = k
++ , hmacKey = MacKey bs }
++ -- It's okay to have a MacKey where bs doesn't
++ -- have exactly 512 bits, the size of the block
++ -- used in SHA-256. hmac' already deals with it.
++
++-- | Same as 'encrypt', however randomly generates the
++-- initialization vector for you.
++encryptIO :: Key -> S.ByteString -> IO S.ByteString
++encryptIO key x = do
++ iv <- randomIV
++ return $ encrypt key iv x
++
++-- | Encrypt (AES-CBC), sign (HMAC-SHA256) and encode (Base64)
++-- the given cookie data. The returned byte string is ready to
++-- be used in a response header.
++encrypt :: Key -- ^ Key of the server.
++ -> IV -- ^ New, random initialization vector (see 'randomIV').
++ -> S.ByteString -- ^ Serialized cookie data.
++ -> S.ByteString -- ^ Encoded cookie data to be given to
++ -- the client browser.
++encrypt key (IV iv) x =
++ B.encode $ S.concat [iv, encode auth, encrypted]
++ where
++ toPad = 16 - S.length x `mod` 16
++ pad = S.replicate toPad $ fromIntegral toPad
++ y = pad `S.append` x
++ encrypted = A.encryptCBC (aesKey key) iv y
++ auth = hmac' (hmacKey key) encrypted :: SHA256
++
++-- | Decode (Base64), verify the integrity and authenticity
++-- (HMAC-SHA256) and decrypt (AES-CBC) the given encoded cookie
++-- data. Returns the original serialized cookie data. Fails if
++-- the data is corrupted.
++decrypt :: Key -- ^ Key of the server.
++ -> S.ByteString -- ^ Encoded cookie data given by the browser.
++ -> Maybe S.ByteString -- ^ Serialized cookie data.
++decrypt key dataBS64 = do
++ dataBS <- either (const Nothing) Just $ B.decode dataBS64
++ if S.length dataBS `mod` 16 /= 0 || S.length dataBS < 48
++ then Nothing
++ else do
++ let (iv, (auth, encrypted)) = second (S.splitAt 32) $ S.splitAt 16 dataBS
++ auth' = hmac' (hmacKey key) encrypted :: SHA256
++ guard (encode auth' == auth)
++ let x = A.decryptCBC (aesKey key) iv encrypted
++ (td, _) <- S.uncons x
++ guard (td > 0 && td <= 16)
++ return $ S.drop (fromIntegral td) x
diff --git a/p/haskell-clientsession/debian/patches/series b/p/haskell-clientsession/debian/patches/series
new file mode 100644
index 000000000..03a022616
--- /dev/null
+++ b/p/haskell-clientsession/debian/patches/series
@@ -0,0 +1 @@
+debian-changes-0.7.0-1