aws-0.0.1: Aws/Signature.hs
{-# LANGUAGE TypeFamilies, OverloadedStrings #-}
module Aws.Signature
where
import Aws.Credentials
import Aws.Query
import Data.Time
import qualified Crypto.HMAC as HMAC
import qualified Crypto.Hash.SHA1 as SHA1
import qualified Crypto.Hash.SHA256 as SHA256
import qualified Data.ByteString as B
import qualified Data.ByteString.Base64 as Base64
import qualified Data.Serialize as Serialize
data TimeInfo
= Timestamp
| ExpiresAt { fromExpiresAt :: UTCTime }
| ExpiresIn { fromExpiresIn :: NominalDiffTime }
deriving (Show)
data AbsoluteTimeInfo
= AbsoluteTimestamp { fromAbsoluteTimestamp :: UTCTime }
| AbsoluteExpires { fromAbsoluteExpires :: UTCTime }
deriving (Show)
fromAbsoluteTimeInfo :: AbsoluteTimeInfo -> UTCTime
fromAbsoluteTimeInfo (AbsoluteTimestamp time) = time
fromAbsoluteTimeInfo (AbsoluteExpires time) = time
makeAbsoluteTimeInfo :: TimeInfo -> UTCTime -> AbsoluteTimeInfo
makeAbsoluteTimeInfo Timestamp now = AbsoluteTimestamp now
makeAbsoluteTimeInfo (ExpiresAt t) _ = AbsoluteExpires t
makeAbsoluteTimeInfo (ExpiresIn s) now = AbsoluteExpires $ addUTCTime s now
data SignatureData
= SignatureData {
signatureTimeInfo :: AbsoluteTimeInfo
, signatureTime :: UTCTime
, signatureCredentials :: Credentials
}
signatureData :: TimeInfo -> Credentials -> IO SignatureData
signatureData rti cr = do
now <- getCurrentTime
let ti = makeAbsoluteTimeInfo rti now
return SignatureData { signatureTimeInfo = ti, signatureTime = now, signatureCredentials = cr }
class SignQuery r where
type Info r :: *
signQuery :: r -> Info r -> SignatureData -> SignedQuery
data AuthorizationHash
= HmacSHA1
| HmacSHA256
deriving (Show)
amzHash :: AuthorizationHash -> B.ByteString
amzHash HmacSHA1 = "HmacSHA1"
amzHash HmacSHA256 = "HmacSHA256"
signature :: Credentials -> AuthorizationHash -> B.ByteString -> B.ByteString
signature cr ah input = Base64.encode sig
where
sig = case ah of
HmacSHA1 -> computeSig (undefined :: SHA1.SHA1)
HmacSHA256 -> computeSig (undefined :: SHA256.SHA256)
computeSig t = Serialize.encode (HMAC.hmac' key input `asTypeOf` t)
key = HMAC.MacKey (secretAccessKey cr)