From 2aede11ad7e5addd50cd4e3c202e094319e942f2 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Thu, 9 Apr 2015 17:29:37 +0200 Subject: Rewording and lint --- src/Crypto/Macaroon.hs | 31 ++++++++++++++++--------------- src/Crypto/Macaroon/Binder.hs | 2 +- src/Crypto/Macaroon/Internal.hs | 33 ++++++++++++++++++--------------- 3 files changed, 35 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/Crypto/Macaroon.hs b/src/Crypto/Macaroon.hs index 819a9eb..42e4a07 100644 --- a/src/Crypto/Macaroon.hs +++ b/src/Crypto/Macaroon.hs @@ -8,18 +8,16 @@ Maintainer : julien.tanguy@jhome.fr Stability : experimental Portability : portable - Pure haskell implementations of macaroons. Warning: this implementation has not been audited by security experts. -Use it with caution. +Do not use in production References: - Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in the Cloud - Time for better security in NoSQL - -} module Crypto.Macaroon ( -- * Types @@ -50,11 +48,14 @@ module Crypto.Macaroon ( import Crypto.Cipher.AES import Crypto.Hash +import Data.Char import Data.Byteable import qualified Data.ByteString as BS import qualified Data.ByteString.Base64.URL as B64 import qualified Data.ByteString.Char8 as B8 import Data.Hex +import Data.Word +import Data.Serialize import Crypto.Macaroon.Internal @@ -62,7 +63,7 @@ import Crypto.Macaroon.Internal create :: Key -> Key -> Location -> Macaroon create secret ident loc = MkMacaroon loc ident [] (toBytes (hmac derivedKey ident :: HMAC SHA256)) where - derivedKey = toBytes $ (hmac "macaroons-key-generator" secret :: HMAC SHA256) + derivedKey = toBytes (hmac "macaroons-key-generator" secret :: HMAC SHA256) caveatLoc :: Caveat -> Location caveatLoc = cl @@ -74,17 +75,7 @@ caveatVId :: Caveat -> Key caveatVId = vid inspect :: Macaroon -> String -inspect m = unlines [ "location " ++ show (location m) - , "identifier " ++ show (identifier m) - , (concatMap (showCav (location m)) (caveats m)) - , "signature " ++ show (hex $ signature m) - ] - where - showCav loc c | cl c == loc && vid c == BS.empty = "cid " ++ show (cid c) - | otherwise = unlines [ "cid " ++ show (cid c) - , "vid " ++ show (vid c) - , "cl " ++ show (cl c) - ] +inspect = show serialize :: Macaroon -> BS.ByteString serialize m = B8.filter (/= '=') . B64.encode $ packets @@ -100,6 +91,16 @@ serialize m = B8.filter (/= '=') . B64.encode $ packets , putPacket "vid" (vid c) , putPacket "cl" (cl c) ] + putPacket key dat = BS.concat [ + B8.map toLower . hex . encode $ (fromIntegral size :: Word16) + , key + , " " + , dat + , "\n" + ] + where + size = 4 + 2 + BS.length key + BS.length dat + diff --git a/src/Crypto/Macaroon/Binder.hs b/src/Crypto/Macaroon/Binder.hs index 3ec3d67..91f07ce 100644 --- a/src/Crypto/Macaroon/Binder.hs +++ b/src/Crypto/Macaroon/Binder.hs @@ -24,5 +24,5 @@ newtype Binder = Binder { bind :: Macaroon -> Macaroon -> BS.ByteString } -- | Binder which concatenates the two signatures and hashes them hashSigs :: Binder -hashSigs = Binder $ \m m' -> toBytes $ (HMAC . hash $ BS.append (toBytes $ signature m') (toBytes $ signature m) :: HMAC SHA256) +hashSigs = Binder $ \m m' -> toBytes (HMAC . hash $ BS.append (toBytes $ signature m') (toBytes $ signature m) :: HMAC SHA256) diff --git a/src/Crypto/Macaroon/Internal.hs b/src/Crypto/Macaroon/Internal.hs index fc50486..82ce0b4 100644 --- a/src/Crypto/Macaroon/Internal.hs +++ b/src/Crypto/Macaroon/Internal.hs @@ -21,10 +21,8 @@ import Data.Byteable import qualified Data.ByteString as BS import qualified Data.ByteString.Base64 as B64 import qualified Data.ByteString.Char8 as B8 -import Data.Char import Data.Hex -import Data.Serialize -import Data.Word +import Data.List -- |Type alias for Macaroons and Caveat keys and identifiers type Key = BS.ByteString @@ -45,6 +43,14 @@ data Macaroon = MkMacaroon { location :: Location -- ^ Macaroon HMAC signature } deriving (Eq) +instance Show Macaroon where + -- We use intercalate because unlines would add a trailing newline + show (MkMacaroon l i c s) = intercalate "\n" [ + "location " ++ B8.unpack l + , "identifier " ++ B8.unpack i + , concatMap show c + , "signature " ++ B8.unpack (hex s) + ] instance NFData Macaroon where rnf (MkMacaroon loc ident cavs sig) = rnf loc `seq` rnf ident `seq` rnf cavs `seq` rnf sig @@ -60,21 +66,18 @@ data Caveat = MkCaveat { cid :: Key } deriving (Eq) +instance Show Caveat where + show (MkCaveat c v l) | v == BS.empty = "cid " ++ B8.unpack c + | otherwise = unlines [ "cid " ++ B8.unpack c + , "vid " ++ B8.unpack v + , "cl " ++ B8.unpack l + ] + + instance NFData Caveat where rnf (MkCaveat cid vid cl) = rnf cid `seq` rnf vid `seq` rnf cl -putPacket :: BS.ByteString -> BS.ByteString -> BS.ByteString -putPacket key dat = BS.concat [ - B8.map toLower . hex . encode $ (fromIntegral size :: Word16) - , key - , " " - , dat - , "\n" - ] - where - size = 4 + 2 + BS.length key + BS.length dat - addCaveat :: Location -> Key -> Key @@ -84,5 +87,5 @@ addCaveat loc cid vid m = m { caveats = cavs ++ [cav'], signature = sig} where cavs = caveats m cav' = MkCaveat cid vid loc - sig = toBytes $ (hmac (signature m) (BS.append vid cid) :: HMAC SHA256) + sig = toBytes (hmac (signature m) (BS.append vid cid) :: HMAC SHA256) -- cgit v1.2.3