module Network.WindowsLive.Secret ( Secret , Key , new , encryptionKey , signingKey ) where import Codec.Utils ( Octet ) import Codec.Text.Raw ( hexdump ) import Text.PrettyPrint.HughesPJ ( text, (<+>), char ) import Control.Monad.Error ( MonadError ) import qualified Data.Digest.SHA256 as SHA256 type Key = [Octet] newtype Secret = Secret [Octet] instance Show Secret where showsPrec _ (Secret bs) = shows $ text "Secret<" <+> hexdump 24 bs <+> char '>' new :: MonadError e m => String -> m Secret new s = if null s then fail "Empty secret" else return $ Secret $ map (toEnum . fromEnum) s data KeyType = Signature | Encryption deriving Show keyPrefix :: KeyType -> Key keyPrefix kt = map (toEnum . fromEnum) $ case kt of Signature -> "SIGNATURE" Encryption -> "ENCRYPTION" -- |Generate a cryptographic key from the secret and the key type key :: Secret -> KeyType -> Key key (Secret bytes) kt = take 16 $ SHA256.hash $ keyPrefix kt ++ bytes encryptionKey :: Secret -> Key encryptionKey = flip key Encryption signingKey :: Secret -> Key signingKey = flip key Signature