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"
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