From 5d1b7d51854d355bf5b6438c1a96ce9e743fd810 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Fri, 15 May 2015 16:03:30 +0200 Subject: Add quickcheck properties --- src/Crypto/Macaroon/Verifier.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/Crypto/Macaroon') diff --git a/src/Crypto/Macaroon/Verifier.hs b/src/Crypto/Macaroon/Verifier.hs index 0d1636c..e257f5f 100644 --- a/src/Crypto/Macaroon/Verifier.hs +++ b/src/Crypto/Macaroon/Verifier.hs @@ -24,10 +24,10 @@ import Crypto.Macaroon.Internal -- | Opaque datatype for now. Might need more explicit errors -data Result = Success | Failure deriving (Show,Eq) +data VResult = VSuccess | VFailure deriving (Show,Eq) -verifySig :: Key -> Macaroon -> Result -verifySig k m = bool Failure Success $ +verifySig :: Key -> Macaroon -> VResult +verifySig k m = bool VFailure VSuccess $ signature m == foldl' hash (toBytes (hmac derivedKey (identifier m) :: HMAC SHA256)) (caveats m) where hash s c = toBytes (hmac s (vid c `BS.append` cid c) :: HMAC SHA256) -- cgit v1.2.3 From b7889567b811ac347acff9983d15ab0e91c76876 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Fri, 15 May 2015 18:17:13 +0200 Subject: Add newlines between Caveats in Macaroon's show [ci skip] --- src/Crypto/Macaroon/Internal.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Crypto/Macaroon') diff --git a/src/Crypto/Macaroon/Internal.hs b/src/Crypto/Macaroon/Internal.hs index 116f5ed..2f56512 100644 --- a/src/Crypto/Macaroon/Internal.hs +++ b/src/Crypto/Macaroon/Internal.hs @@ -58,7 +58,7 @@ instance Show Macaroon where show (MkMacaroon l i c s) = intercalate "\n" [ "location " ++ B8.unpack l , "identifier " ++ B8.unpack i - , concatMap show c + , intercalate "\n" (map show c) , "signature " ++ B8.unpack (hex s) ] -- cgit v1.2.3 From 6f3c0dca02c1069115bc2592c439970d2af07cc5 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Fri, 15 May 2015 22:31:05 +0200 Subject: Add basic exact caveat verifiers Need more tests Touching #2 Verify first party caveats --- src/Crypto/Macaroon/Verifier.hs | 47 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) (limited to 'src/Crypto/Macaroon') diff --git a/src/Crypto/Macaroon/Verifier.hs b/src/Crypto/Macaroon/Verifier.hs index e257f5f..cb64c9d 100644 --- a/src/Crypto/Macaroon/Verifier.hs +++ b/src/Crypto/Macaroon/Verifier.hs @@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} {-| Module : Crypto.Macaroon.Verifier Copyright : (c) 2015 Julien Tanguy @@ -11,7 +12,14 @@ Portability : portable -} -module Crypto.Macaroon.Verifier where +module Crypto.Macaroon.Verifier ( + Verified(..) + , verifySig + , verifyExact + , verifyCavs + -- , module Data.Attoparsec.ByteString + , module Data.Attoparsec.ByteString.Char8 +) where import Crypto.Hash @@ -19,16 +27,47 @@ import Data.Bool import qualified Data.ByteString as BS import Data.Byteable import Data.Foldable +import Data.Maybe +import Data.Attoparsec.ByteString +import Data.Attoparsec.ByteString.Char8 import Crypto.Macaroon.Internal -- | Opaque datatype for now. Might need more explicit errors -data VResult = VSuccess | VFailure deriving (Show,Eq) +data Verified = Ok | Failed deriving (Show,Eq) -verifySig :: Key -> Macaroon -> VResult -verifySig k m = bool VFailure VSuccess $ +instance Monoid Verified where + mempty = Ok + mappend Ok Ok = Ok + mappend _ _ = Failed + + +type CaveatVerifier = Caveat -> Maybe Verified + +verifySig :: Key -> Macaroon -> Verified +verifySig k m = bool Failed Ok $ signature m == foldl' hash (toBytes (hmac derivedKey (identifier m) :: HMAC SHA256)) (caveats m) where hash s c = toBytes (hmac s (vid c `BS.append` cid c) :: HMAC SHA256) derivedKey = toBytes (hmac "macaroons-key-generator" k :: HMAC SHA256) + +verifyCavs :: [Caveat -> Maybe Verified] -> Macaroon -> Verified +verifyCavs verifiers m = mconcat $ map (\c -> mconcat . catMaybes $ map ($ c) verifiers) (caveats m) + +verifyExact :: (Show a, Eq a) => Key -> a -> Parser a -> Caveat -> Maybe Verified +verifyExact key expected parser cav = if key `BS.isPrefixOf` cid cav then + case parseOnly kvparser (cid cav) of + Right v -> verify <$> Just v + Left _ -> Just Failed + else Nothing + where + kvparser = do + key <- string key + skipSpace + string "=" + skipSpace + parser + + -- *> skipSpace *> string "=" *> skipSpace *> parser <* endOfInput + verify a = bool Failed Ok (a == expected) -- cgit v1.2.3 From 857f2f3ba8ba2de9ab65ea3c66eafb718fe4e1a6 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Fri, 15 May 2015 23:02:22 +0200 Subject: Add generalized function verifier --- src/Crypto/Macaroon/Verifier.hs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/Crypto/Macaroon') diff --git a/src/Crypto/Macaroon/Verifier.hs b/src/Crypto/Macaroon/Verifier.hs index cb64c9d..012d156 100644 --- a/src/Crypto/Macaroon/Verifier.hs +++ b/src/Crypto/Macaroon/Verifier.hs @@ -16,6 +16,7 @@ module Crypto.Macaroon.Verifier ( Verified(..) , verifySig , verifyExact + , verifyFun , verifyCavs -- , module Data.Attoparsec.ByteString , module Data.Attoparsec.ByteString.Char8 @@ -55,10 +56,13 @@ verifySig k m = bool Failed Ok $ verifyCavs :: [Caveat -> Maybe Verified] -> Macaroon -> Verified verifyCavs verifiers m = mconcat $ map (\c -> mconcat . catMaybes $ map ($ c) verifiers) (caveats m) -verifyExact :: (Show a, Eq a) => Key -> a -> Parser a -> Caveat -> Maybe Verified -verifyExact key expected parser cav = if key `BS.isPrefixOf` cid cav then +verifyExact :: (Eq a) => Key -> a -> Parser a -> Caveat -> Maybe Verified +verifyExact k expected = verifyFun k (expected ==) + +verifyFun :: Key -> (a -> Bool) -> Parser a -> Caveat -> Maybe Verified +verifyFun key f parser cav = if key `BS.isPrefixOf` cid cav then case parseOnly kvparser (cid cav) of - Right v -> verify <$> Just v + Right v -> (bool Failed Ok . f) <$> Just v Left _ -> Just Failed else Nothing where @@ -67,7 +71,4 @@ verifyExact key expected parser cav = if key `BS.isPrefixOf` cid cav then skipSpace string "=" skipSpace - parser - - -- *> skipSpace *> string "=" *> skipSpace *> parser <* endOfInput - verify a = bool Failed Ok (a == expected) + parser <* endOfInput -- cgit v1.2.3 From 90695615c54b5939d7286e777cb1b19a221616b9 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Sat, 16 May 2015 02:12:14 +0200 Subject: Fix caveat verification QuickCheck properties > HUnit tests --- src/Crypto/Macaroon/Verifier.hs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/Crypto/Macaroon') diff --git a/src/Crypto/Macaroon/Verifier.hs b/src/Crypto/Macaroon/Verifier.hs index 012d156..4eedff5 100644 --- a/src/Crypto/Macaroon/Verifier.hs +++ b/src/Crypto/Macaroon/Verifier.hs @@ -14,6 +14,8 @@ Portability : portable -} module Crypto.Macaroon.Verifier ( Verified(..) + , CaveatVerifier(..) + , () , verifySig , verifyExact , verifyFun @@ -28,7 +30,9 @@ import Data.Bool import qualified Data.ByteString as BS import Data.Byteable import Data.Foldable +import Data.Function import Data.Maybe +import Data.Traversable import Data.Attoparsec.ByteString import Data.Attoparsec.ByteString.Char8 @@ -44,7 +48,16 @@ instance Monoid Verified where mappend _ _ = Failed -type CaveatVerifier = Caveat -> Maybe Verified +data CaveatVerifier = CV { vFun :: Caveat -> Maybe Verified , helpText :: String} + +instance Eq CaveatVerifier where + (==) = (==) `on` helpText + +instance Show CaveatVerifier where + show = helpText + +() :: (Caveat -> Maybe Verified) -> String -> CaveatVerifier +f t = CV f t verifySig :: Key -> Macaroon -> Verified verifySig k m = bool Failed Ok $ @@ -53,8 +66,8 @@ verifySig k m = bool Failed Ok $ hash s c = toBytes (hmac s (vid c `BS.append` cid c) :: HMAC SHA256) derivedKey = toBytes (hmac "macaroons-key-generator" k :: HMAC SHA256) -verifyCavs :: [Caveat -> Maybe Verified] -> Macaroon -> Verified -verifyCavs verifiers m = mconcat $ map (\c -> mconcat . catMaybes $ map ($ c) verifiers) (caveats m) +verifyCavs :: [CaveatVerifier] -> Macaroon -> Verified +verifyCavs verifiers m = foldMap (\c -> fromMaybe Failed $ foldMap (($ c) . vFun) verifiers) (caveats m) verifyExact :: (Eq a) => Key -> a -> Parser a -> Caveat -> Maybe Verified verifyExact k expected = verifyFun k (expected ==) -- cgit v1.2.3 From 62576139b8dbf2cd0d3c04e927b9df2d0805a199 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Sat, 16 May 2015 12:51:22 +0200 Subject: Add Sig/cav verifier [ci skip] --- src/Crypto/Macaroon/Verifier.hs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/Crypto/Macaroon') diff --git a/src/Crypto/Macaroon/Verifier.hs b/src/Crypto/Macaroon/Verifier.hs index 4eedff5..02cb448 100644 --- a/src/Crypto/Macaroon/Verifier.hs +++ b/src/Crypto/Macaroon/Verifier.hs @@ -14,14 +14,14 @@ Portability : portable -} module Crypto.Macaroon.Verifier ( Verified(..) - , CaveatVerifier(..) + , CaveatVerifier , () + , verifyMacaroon , verifySig , verifyExact , verifyFun - , verifyCavs - -- , module Data.Attoparsec.ByteString , module Data.Attoparsec.ByteString.Char8 + , verifyCavs ) where @@ -66,6 +66,10 @@ verifySig k m = bool Failed Ok $ hash s c = toBytes (hmac s (vid c `BS.append` cid c) :: HMAC SHA256) derivedKey = toBytes (hmac "macaroons-key-generator" k :: HMAC SHA256) +verifyMacaroon :: Key -> [CaveatVerifier] -> Macaroon -> Verified +verifyMacaroon secret verifiers m = verifySig secret m `mappend` verifyCavs verifiers m + + verifyCavs :: [CaveatVerifier] -> Macaroon -> Verified verifyCavs verifiers m = foldMap (\c -> fromMaybe Failed $ foldMap (($ c) . vFun) verifiers) (caveats m) -- cgit v1.2.3