From c830f7c2cf925ce340f4097d76ea2a3bc94cb4a6 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Wed, 8 Jul 2015 18:13:14 +0200 Subject: Rewrite Verifier with Validation --- src/Crypto/Macaroon/Verifier.hs | 73 +++++++++++++---------------------------- 1 file changed, 22 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/Crypto/Macaroon/Verifier.hs b/src/Crypto/Macaroon/Verifier.hs index 02cb448..713a971 100644 --- a/src/Crypto/Macaroon/Verifier.hs +++ b/src/Crypto/Macaroon/Verifier.hs @@ -1,5 +1,5 @@ {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE RankNTypes #-} {-| Module : Crypto.Macaroon.Verifier Copyright : (c) 2015 Julien Tanguy @@ -13,79 +13,50 @@ Portability : portable -} module Crypto.Macaroon.Verifier ( - Verified(..) - , CaveatVerifier - , () + Verifier , verifyMacaroon , verifySig - , verifyExact - , verifyFun + -- , verifyExact + -- , verifyFun , module Data.Attoparsec.ByteString.Char8 , verifyCavs ) where import Crypto.Hash +import Data.Attoparsec.ByteString +import Data.Attoparsec.ByteString.Char8 import Data.Bool -import qualified Data.ByteString as BS import Data.Byteable +import qualified Data.ByteString as BS +import Data.Either +import Data.Either.Validation import Data.Foldable import Data.Function import Data.Maybe import Data.Traversable -import Data.Attoparsec.ByteString -import Data.Attoparsec.ByteString.Char8 import Crypto.Macaroon.Internal +type Verifier = Caveat -> Maybe (Either String Caveat) --- | Opaque datatype for now. Might need more explicit errors -data Verified = Ok | Failed deriving (Show,Eq) - -instance Monoid Verified where - mempty = Ok - mappend Ok Ok = Ok - mappend _ _ = Failed - - -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 $ +verifySig :: Key -> Macaroon -> Either String Macaroon +verifySig k m = bool (Left "Signatures do not match") (Right m) $ 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) -verifyMacaroon :: Key -> [CaveatVerifier] -> Macaroon -> Verified -verifyMacaroon secret verifiers m = verifySig secret m `mappend` verifyCavs verifiers m - +verifyMacaroon :: Key -> [Verifier] -> Macaroon -> Either String Macaroon +verifyMacaroon secret verifiers m = verifySig secret m >>= verifyCavs verifiers -verifyCavs :: [CaveatVerifier] -> Macaroon -> Verified -verifyCavs verifiers m = foldMap (\c -> fromMaybe Failed $ foldMap (($ c) . vFun) verifiers) (caveats m) +verifyCavs :: [Verifier] -> Macaroon -> Either String Macaroon +verifyCavs verifiers m = case partitionEithers verifiedCaveats of + ([],_) -> Right m + (errs,_) -> Left (mconcat errs) + where + verifiedCaveats = map (\c -> defaultFail c $ foldMap (fmap eitherToValidation . ($c)) verifiers) $ caveats m + defaultFail c = maybe (Left ("No validation for this caveat: " ++ show c)) validationToEither -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 -> (bool Failed Ok . f) <$> Just v - Left _ -> Just Failed - else Nothing - where - kvparser = do - key <- string key - skipSpace - string "=" - skipSpace - parser <* endOfInput +-- TODO: define API -- cgit v1.2.3 From 7f9f7386fdbe8d19ef30ebd20939e67cc8bb145c Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Sun, 16 Aug 2015 23:22:10 +0200 Subject: Basic validation functions Still needs testing [ci skip] --- src/Crypto/Macaroon/Verifier.hs | 81 ++++++++++++++++++-------------- src/Crypto/Macaroon/Verifier/Internal.hs | 74 +++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 34 deletions(-) create mode 100644 src/Crypto/Macaroon/Verifier/Internal.hs (limited to 'src') diff --git a/src/Crypto/Macaroon/Verifier.hs b/src/Crypto/Macaroon/Verifier.hs index 713a971..7d5f094 100644 --- a/src/Crypto/Macaroon/Verifier.hs +++ b/src/Crypto/Macaroon/Verifier.hs @@ -1,5 +1,8 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE TypeSynonymInstances #-} +{-# LANGUAGE UndecidableInstances #-} {-| Module : Crypto.Macaroon.Verifier Copyright : (c) 2015 Julien Tanguy @@ -13,50 +16,60 @@ Portability : portable -} module Crypto.Macaroon.Verifier ( - Verifier - , verifyMacaroon - , verifySig - -- , verifyExact - -- , verifyFun - , module Data.Attoparsec.ByteString.Char8 - , verifyCavs + verify + , ValidationError(ValidatorError, ParseError) + -- , (.<), (.<=), (.==), (.>), (.>=) + -- , module Data.Attoparsec.ByteString.Char8 ) where -import Crypto.Hash +import Control.Monad +import Control.Monad.IO.Class import Data.Attoparsec.ByteString import Data.Attoparsec.ByteString.Char8 import Data.Bool -import Data.Byteable import qualified Data.ByteString as BS -import Data.Either -import Data.Either.Validation -import Data.Foldable -import Data.Function -import Data.Maybe -import Data.Traversable +import Data.Either.Combinators import Crypto.Macaroon.Internal +import Crypto.Macaroon.Verifier.Internal -type Verifier = Caveat -> Maybe (Either String Caveat) -verifySig :: Key -> Macaroon -> Either String Macaroon -verifySig k m = bool (Left "Signatures do not match") (Right m) $ - 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) -verifyMacaroon :: Key -> [Verifier] -> Macaroon -> Either String Macaroon -verifyMacaroon secret verifiers m = verifySig secret m >>= verifyCavs verifiers -verifyCavs :: [Verifier] -> Macaroon -> Either String Macaroon -verifyCavs verifiers m = case partitionEithers verifiedCaveats of - ([],_) -> Right m - (errs,_) -> Left (mconcat errs) - where - verifiedCaveats = map (\c -> defaultFail c $ foldMap (fmap eitherToValidation . ($c)) verifiers) $ caveats m - defaultFail c = maybe (Left ("No validation for this caveat: " ++ show c)) validationToEither +-- (.<) :: (MonadIO m, Ord a, Parsable a) => Key -> m a -> Caveat -> m (Maybe (Either ValidationError Caveat)) +-- (.<) = verifyOpBool "Greater or equal" (<) "<" + +-- (.<=) :: (MonadIO m, Ord a, Parsable a) => Key -> m a -> Caveat -> m (Maybe (Either ValidationError Caveat)) +-- (.<=) = verifyOpBool "Strictly greater" (<=) "<=" + +-- (.==) :: (MonadIO m, Eq a, Parsable a) => Key -> m a -> Caveat -> m (Maybe (Either ValidationError Caveat)) +-- (.==) = verifyOpBool "Not equal" (==) "=" + +-- (.>) :: (MonadIO m, Ord a, Parsable a) => Key -> m a -> Caveat -> m (Maybe (Either ValidationError Caveat)) +-- (.>) = verifyOpBool "Less or equal" (>) ">" + +-- (.>=) :: (MonadIO m, Ord a, Parsable a) => Key -> m a -> Caveat -> m (Maybe (Either ValidationError Caveat)) +-- (.>=) = verifyOpBool "Strictly less" (>=) ">=" --- TODO: define API +verify :: MonadIO m => Key -> [Caveat -> m (Maybe (Either ValidationError Caveat))] -> Macaroon -> m (Either ValidationError Macaroon) +verify secret verifiers m = join <$> forM (verifySig secret m) (verifyCavs verifiers) + + +-- verifyOpBool :: MonadIO m => String -> Parser a -> (a -> a -> Bool) -> BS.ByteString -> Key -> m a -> Caveat -> m (Maybe (Either ValidationError Caveat)) +-- verifyOpBool err p f op k val = verifyParser k valueParser $ \s -> do +-- expected <- val +-- return $ bool (Left $ ValidatorError err) (Right Win) =<< f expected <$> mapLeft ParseError (parseOnly p s) +-- where +-- valueParser = string op *> skipSpace *> takeByteString + +verifyParser :: (MonadIO m) => Key -> Parser a -> (a -> m (Either ValidationError Win)) -> Caveat -> m (Maybe (Either ValidationError Caveat)) +verifyParser k p f c = case parseOnly keyParser . cid $ c of + Left _ -> return Nothing + Right bs -> Just <$> case parseOnly p bs of + Left err -> return $ Left $ ParseError err + Right a -> fmap (const c) <$> f a + where + keyParser = string k *> skipSpace *> takeByteString + diff --git a/src/Crypto/Macaroon/Verifier/Internal.hs b/src/Crypto/Macaroon/Verifier/Internal.hs new file mode 100644 index 0000000..63d826d --- /dev/null +++ b/src/Crypto/Macaroon/Verifier/Internal.hs @@ -0,0 +1,74 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} +{-| +Module : Crypto.Macaroon.Verifier.Internal +Copyright : (c) 2015 Julien Tanguy +License : BSD3 + +Maintainer : julien.tanguy@jhome.fr +Stability : experimental +Portability : portable + + + +-} +module Crypto.Macaroon.Verifier.Internal where + +import Control.Monad +import Control.Monad.IO.Class +import Crypto.Hash +import Data.Bool +import Data.Byteable +import qualified Data.ByteString as BS +import Data.Either +import Data.Either.Validation +import Data.Foldable +import Data.Maybe + +import Crypto.Macaroon.Internal + +data Win = Win + +data ValidationError = SigMismatch + | NoVerifier + | ParseError String + | ValidatorError String + deriving Show + +instance Monoid ValidationError where + mempty = NoVerifier + NoVerifier `mappend` e = e + e `mappend` NoVerifier = e + SigMismatch `mappend` _ = SigMismatch + _ `mappend` SigMismatch = SigMismatch + (ValidatorError e) `mappend` (ParseError _) = ValidatorError e + (ParseError _) `mappend` (ValidatorError e) = ValidatorError e + + +verifySig :: Key -> Macaroon -> Either ValidationError Macaroon +verifySig k m = bool (Left SigMismatch) (Right m) $ + 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 :: MonadIO m + => [Caveat -> m (Maybe (Either ValidationError Caveat))] + -> Macaroon + -> m (Either ValidationError Macaroon) +verifyCavs verifiers m = gatherEithers <$> mapM validateCaveat (caveats m) + where + {- + - validateCaveat :: Caveat -> m (Validation String Caveat) + - We can use fromJust here safely since we use a `Just Failure` as a + - starting value for the foldM. We are guaranteed to have a `Just something` + - from it. + -} + validateCaveat c = fromJust <$> foldM (\res v -> mappend res . fmap eitherToValidation <$> v c) (defErr c) verifiers + -- defErr :: Caveat -> Maybe (Validation String Caveat) + defErr c = Just $ Failure NoVerifier + -- gatherEithers :: [Validation String Caveat] -> Either String Caveat + gatherEithers vs = case partitionEithers . map validationToEither $ vs of + ([],_) -> Right m + (errs,_) -> Left (mconcat errs) -- cgit v1.2.3 From bf31e29028a4402ea0d2deefdb3b86efd526acd0 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Mon, 17 Aug 2015 17:36:35 +0200 Subject: Typos and stylish-haskell --- src/Crypto/Macaroon/Verifier/Internal.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Crypto/Macaroon/Verifier/Internal.hs b/src/Crypto/Macaroon/Verifier/Internal.hs index 63d826d..b65b62d 100644 --- a/src/Crypto/Macaroon/Verifier/Internal.hs +++ b/src/Crypto/Macaroon/Verifier/Internal.hs @@ -44,7 +44,7 @@ instance Monoid ValidationError where (ValidatorError e) `mappend` (ParseError _) = ValidatorError e (ParseError _) `mappend` (ValidatorError e) = ValidatorError e - +-- | Check that the given macaroon has a correct signature verifySig :: Key -> Macaroon -> Either ValidationError Macaroon verifySig k m = bool (Left SigMismatch) (Right m) $ signature m == foldl' hash (toBytes (hmac derivedKey (identifier m) :: HMAC SHA256)) (caveats m) -- cgit v1.2.3 From 86f3882318d323d1920ca1c7da6e816f0ed376da Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Mon, 17 Aug 2015 17:38:24 +0200 Subject: Change verifier api and split Verifier module - Added haddocks --- src/Crypto/Macaroon.hs | 21 +++++-------------- src/Crypto/Macaroon/Internal.hs | 6 +++++- src/Crypto/Macaroon/Verifier.hs | 35 +++++++++++++++++++++++--------- src/Crypto/Macaroon/Verifier/Internal.hs | 30 +++++++++++++++------------ 4 files changed, 52 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/Crypto/Macaroon.hs b/src/Crypto/Macaroon.hs index bfcf8df..c9c8c21 100644 --- a/src/Crypto/Macaroon.hs +++ b/src/Crypto/Macaroon.hs @@ -23,6 +23,7 @@ module Crypto.Macaroon ( -- * Types Macaroon , Caveat + , Secret , Key , Location , Sig @@ -33,9 +34,9 @@ module Crypto.Macaroon ( , caveats , signature -- ** Caveats - , caveatLoc - , caveatId - , caveatVId + , cl + , cid + , vid -- * Create Macaroons , create @@ -54,23 +55,11 @@ import qualified Data.ByteString.Char8 as B8 import Crypto.Macaroon.Internal -- | Create a Macaroon from its key, identifier and location -create :: Key -> Key -> Location -> Macaroon +create :: Secret -> 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) --- | Caveat target location -caveatLoc :: Caveat -> Location -caveatLoc = cl - --- | Caveat identifier -caveatId :: Caveat -> Key -caveatId = cid - --- | Caveat verification identifier -caveatVId :: Caveat -> Key -caveatVId = vid - -- | Inspect a macaroon's contents. For debugging purposes. inspect :: Macaroon -> String inspect = show diff --git a/src/Crypto/Macaroon/Internal.hs b/src/Crypto/Macaroon/Internal.hs index 2f56512..d6e80d3 100644 --- a/src/Crypto/Macaroon/Internal.hs +++ b/src/Crypto/Macaroon/Internal.hs @@ -23,7 +23,11 @@ import qualified Data.ByteString.Char8 as B8 import Data.Hex import Data.List --- |Type alias for Macaroons and Caveat keys and identifiers + +-- |Type alias for Macaroons secret keys +type Secret = BS.ByteString + +-- |Type alias for Macaroons and Caveat and identifiers type Key = BS.ByteString -- |Type alias for Macaroons and Caveat locations diff --git a/src/Crypto/Macaroon/Verifier.hs b/src/Crypto/Macaroon/Verifier.hs index 7d5f094..a739437 100644 --- a/src/Crypto/Macaroon/Verifier.hs +++ b/src/Crypto/Macaroon/Verifier.hs @@ -52,8 +52,23 @@ import Crypto.Macaroon.Verifier.Internal -- (.>=) :: (MonadIO m, Ord a, Parsable a) => Key -> m a -> Caveat -> m (Maybe (Either ValidationError Caveat)) -- (.>=) = verifyOpBool "Strictly less" (>=) ">=" - -verify :: MonadIO m => Key -> [Caveat -> m (Maybe (Either ValidationError Caveat))] -> Macaroon -> m (Either ValidationError Macaroon) +-- | Verify a Macaroon's signature and caveats, given the corresponding Secret +-- and verifiers. +-- +-- A verifier is a function of type +-- @'MonadIO' m => 'Caveat' -> m ('Maybe' ('Either' 'ValidatorError' 'Caveat'))@. +-- +-- It should return: +-- +-- * 'Nothing' if the caveat is not related to the verifier +-- (for instance a time verifier is given an action caveat); +-- * 'Just' ('Left' ('ParseError' reason)) if the verifier is related to the +-- caveat, but failed to parse it completely; +-- * 'Just' ('Left' ('ValidatorError' reason)) if the verifier is related to the +-- caveat, parsed it and invalidated it; +-- * 'Just' ('Right' '()') if the verifier has successfully verified the +-- given caveat +verify :: MonadIO m => Secret -> [Caveat -> m (Maybe (Either ValidationError ()))] -> Macaroon -> m (Either ValidationError Macaroon) verify secret verifiers m = join <$> forM (verifySig secret m) (verifyCavs verifiers) @@ -64,12 +79,12 @@ verify secret verifiers m = join <$> forM (verifySig secret m) (verifyCavs verif -- where -- valueParser = string op *> skipSpace *> takeByteString -verifyParser :: (MonadIO m) => Key -> Parser a -> (a -> m (Either ValidationError Win)) -> Caveat -> m (Maybe (Either ValidationError Caveat)) -verifyParser k p f c = case parseOnly keyParser . cid $ c of - Left _ -> return Nothing - Right bs -> Just <$> case parseOnly p bs of - Left err -> return $ Left $ ParseError err - Right a -> fmap (const c) <$> f a - where - keyParser = string k *> skipSpace *> takeByteString +-- verifyParser :: (MonadIO m) => Key -> Parser a -> (a -> m (Either ValidationError Win)) -> Caveat -> m (Maybe (Either ValidationError Caveat)) +-- verifyParser k p f c = case parseOnly keyParser . cid $ c of +-- Left _ -> return Nothing +-- Right bs -> Just <$> case parseOnly p bs of +-- Left err -> return $ Left $ ParseError err +-- Right a -> fmap (const c) <$> f a +-- where +-- keyParser = string k *> skipSpace *> takeByteString diff --git a/src/Crypto/Macaroon/Verifier/Internal.hs b/src/Crypto/Macaroon/Verifier/Internal.hs index b65b62d..2af55d3 100644 --- a/src/Crypto/Macaroon/Verifier/Internal.hs +++ b/src/Crypto/Macaroon/Verifier/Internal.hs @@ -1,5 +1,5 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} {-| Module : Crypto.Macaroon.Verifier.Internal Copyright : (c) 2015 Julien Tanguy @@ -19,22 +19,26 @@ import Control.Monad.IO.Class import Crypto.Hash import Data.Bool import Data.Byteable -import qualified Data.ByteString as BS +import qualified Data.ByteString as BS import Data.Either import Data.Either.Validation import Data.Foldable import Data.Maybe +import Data.Monoid import Crypto.Macaroon.Internal -data Win = Win - -data ValidationError = SigMismatch - | NoVerifier - | ParseError String - | ValidatorError String - deriving Show +-- | Type representing different validation errors. +-- Only 'ParseError' and 'ValidatorError' are exported, 'SigMismatch' and +-- 'NoVerifier' are used internally and should not be used by the user +data ValidationError = SigMismatch -- ^ Signatures do not match + | NoVerifier -- ^ No verifier can handle a given caveat + | ParseError String -- ^ A verifier had a parse error + | ValidatorError String -- ^ A verifier failed + deriving (Show,Eq) +-- | The 'Monoid' instance is written so 'SigMismatch' is an annihilator, +-- and 'NoVerifier' is the identity element instance Monoid ValidationError where mempty = NoVerifier NoVerifier `mappend` e = e @@ -52,9 +56,9 @@ verifySig k m = bool (Left SigMismatch) (Right m) $ hash s c = toBytes (hmac s (vid c `BS.append` cid c) :: HMAC SHA256) derivedKey = toBytes (hmac "macaroons-key-generator" k :: HMAC SHA256) - +-- | Given a list of verifiers, verify each caveat of the given macaroon verifyCavs :: MonadIO m - => [Caveat -> m (Maybe (Either ValidationError Caveat))] + => [Caveat -> m (Maybe (Either ValidationError ()))] -> Macaroon -> m (Either ValidationError Macaroon) verifyCavs verifiers m = gatherEithers <$> mapM validateCaveat (caveats m) @@ -65,7 +69,7 @@ verifyCavs verifiers m = gatherEithers <$> mapM validateCaveat (caveats m) - starting value for the foldM. We are guaranteed to have a `Just something` - from it. -} - validateCaveat c = fromJust <$> foldM (\res v -> mappend res . fmap eitherToValidation <$> v c) (defErr c) verifiers + validateCaveat c = fmap (const c) . fromJust <$> foldM (\res v -> mappend res . fmap eitherToValidation <$> v c) (defErr c) verifiers -- defErr :: Caveat -> Maybe (Validation String Caveat) defErr c = Just $ Failure NoVerifier -- gatherEithers :: [Validation String Caveat] -> Either String Caveat -- cgit v1.2.3 From 1fcdeab5264180025ac2e48db312c1fbd5ae22ca Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Mon, 17 Aug 2015 18:21:14 +0200 Subject: Import Control.Applicative --- src/Crypto/Macaroon/Verifier/Internal.hs | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/Crypto/Macaroon/Verifier/Internal.hs b/src/Crypto/Macaroon/Verifier/Internal.hs index 2af55d3..73eb66a 100644 --- a/src/Crypto/Macaroon/Verifier/Internal.hs +++ b/src/Crypto/Macaroon/Verifier/Internal.hs @@ -14,6 +14,7 @@ Portability : portable -} module Crypto.Macaroon.Verifier.Internal where +import Control.Applicative import Control.Monad import Control.Monad.IO.Class import Crypto.Hash -- cgit v1.2.3 From a11f20be0fadf21cc96164b49305b59ac7445aa2 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Mon, 17 Aug 2015 18:56:12 +0200 Subject: ghc<7.10.1 compat --- src/Crypto/Macaroon/Verifier.hs | 6 ++++-- src/Crypto/Macaroon/Verifier/Internal.hs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Crypto/Macaroon/Verifier.hs b/src/Crypto/Macaroon/Verifier.hs index a739437..4fc6aff 100644 --- a/src/Crypto/Macaroon/Verifier.hs +++ b/src/Crypto/Macaroon/Verifier.hs @@ -23,11 +23,13 @@ module Crypto.Macaroon.Verifier ( ) where -import Control.Monad +import Control.Applicative +import Control.Monad hiding (forM) import Control.Monad.IO.Class import Data.Attoparsec.ByteString import Data.Attoparsec.ByteString.Char8 import Data.Bool +import Data.Traversable import qualified Data.ByteString as BS import Data.Either.Combinators @@ -68,7 +70,7 @@ import Crypto.Macaroon.Verifier.Internal -- caveat, parsed it and invalidated it; -- * 'Just' ('Right' '()') if the verifier has successfully verified the -- given caveat -verify :: MonadIO m => Secret -> [Caveat -> m (Maybe (Either ValidationError ()))] -> Macaroon -> m (Either ValidationError Macaroon) +verify :: (Functor m, MonadIO m) => Secret -> [Caveat -> m (Maybe (Either ValidationError ()))] -> Macaroon -> m (Either ValidationError Macaroon) verify secret verifiers m = join <$> forM (verifySig secret m) (verifyCavs verifiers) diff --git a/src/Crypto/Macaroon/Verifier/Internal.hs b/src/Crypto/Macaroon/Verifier/Internal.hs index 73eb66a..5126b2e 100644 --- a/src/Crypto/Macaroon/Verifier/Internal.hs +++ b/src/Crypto/Macaroon/Verifier/Internal.hs @@ -58,7 +58,7 @@ verifySig k m = bool (Left SigMismatch) (Right m) $ derivedKey = toBytes (hmac "macaroons-key-generator" k :: HMAC SHA256) -- | Given a list of verifiers, verify each caveat of the given macaroon -verifyCavs :: MonadIO m +verifyCavs :: (Functor m, MonadIO m) => [Caveat -> m (Maybe (Either ValidationError ()))] -> Macaroon -> m (Either ValidationError Macaroon) -- cgit v1.2.3 From 27d5a3a43c7d736f8cd842f14f3178d532de9152 Mon Sep 17 00:00:00 2001 From: Julien Tanguy Date: Mon, 17 Aug 2015 19:39:05 +0200 Subject: Modify exports & haddock --- src/Crypto/Macaroon.hs | 12 +++++++----- src/Crypto/Macaroon/Verifier/Internal.hs | 8 ++++---- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Crypto/Macaroon.hs b/src/Crypto/Macaroon.hs index c9c8c21..86d8eb7 100644 --- a/src/Crypto/Macaroon.hs +++ b/src/Crypto/Macaroon.hs @@ -43,16 +43,20 @@ module Crypto.Macaroon ( , inspect , addFirstPartyCaveat -- , addThirdPartyCaveat + -- * Serialize + , module Crypto.Macaroon.Serializer.Base64 + -- * Verify + , module Crypto.Macaroon.Verifier ) where -- import Crypto.Cipher.AES import Crypto.Hash 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 qualified Data.ByteString as BS import Crypto.Macaroon.Internal +import Crypto.Macaroon.Serializer.Base64 +import Crypto.Macaroon.Verifier -- | Create a Macaroon from its key, identifier and location create :: Secret -> Key -> Location -> Macaroon @@ -78,5 +82,3 @@ addFirstPartyCaveat ident m = addCaveat (location m) ident BS.empty m -- addThirdPartyCaveat key cid loc m = addCaveat loc cid vid m -- where -- vid = encryptECB (initAES (signature m)) key - - diff --git a/src/Crypto/Macaroon/Verifier/Internal.hs b/src/Crypto/Macaroon/Verifier/Internal.hs index 5126b2e..b3ad7f2 100644 --- a/src/Crypto/Macaroon/Verifier/Internal.hs +++ b/src/Crypto/Macaroon/Verifier/Internal.hs @@ -30,16 +30,16 @@ import Data.Monoid import Crypto.Macaroon.Internal -- | Type representing different validation errors. --- Only 'ParseError' and 'ValidatorError' are exported, 'SigMismatch' and --- 'NoVerifier' are used internally and should not be used by the user +-- Only 'ParseError' and 'ValidatorError' are exported, @SigMismatch@ and +-- @NoVerifier@ are used internally and should not be used by the user data ValidationError = SigMismatch -- ^ Signatures do not match | NoVerifier -- ^ No verifier can handle a given caveat | ParseError String -- ^ A verifier had a parse error | ValidatorError String -- ^ A verifier failed deriving (Show,Eq) --- | The 'Monoid' instance is written so 'SigMismatch' is an annihilator, --- and 'NoVerifier' is the identity element +-- | The 'Monoid' instance is written so @SigMismatch@ is an annihilator, +-- and @NoVerifier@ is the identity element instance Monoid ValidationError where mempty = NoVerifier NoVerifier `mappend` e = e -- cgit v1.2.3