sasl-0.0.0.0: src/Network/Sasl/ScramSha1/ScramSha1.hs
{-# LANGUAGE OverloadedStrings #-}
module Network.Sasl.ScramSha1.ScramSha1 (
clientFirstMessageBare,
serverFirstMessage,
clientFinalMessageWithoutProof,
serverFinalMessage,
readClientFirstMessage,
readServerFirstMessage,
readClientFinalMessage,
readServerFinalMessage,
xo, hash,
saltedPassword, clientKey, storedKey, serverKey,
clientSignature, clientProof,
) where
import Control.Applicative
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Base64 as B64
import Network.Sasl.ScramSha1.Fields
import Network.Sasl.ScramSha1.Functions
clientFirstMessageBare :: BS.ByteString -> BS.ByteString -> BS.ByteString
clientFirstMessageBare un nnc = BS.concat ["n=", un, ",r=", nnc]
serverFirstMessage :: BS.ByteString -> BS.ByteString -> Int -> BS.ByteString
serverFirstMessage snnc slt i = BS.concat
["r=", snnc, ",s=", B64.encode slt, ",i=", BSC.pack $ show i]
clientFinalMessageWithoutProof :: BS.ByteString -> BS.ByteString -> BS.ByteString
clientFinalMessageWithoutProof cb snnc =
BS.concat ["c=", B64.encode cb, ",r=", snnc]
serverFinalMessage :: BS.ByteString -> BS.ByteString -> BS.ByteString
serverFinalMessage sk am = BS.concat ["v=", serverSignature sk am]
-- serverSignature (serverKey $ saltedPassword ps slt i) am ]
readClientFirstMessage :: BS.ByteString -> Maybe (BS.ByteString, BS.ByteString)
readClientFirstMessage rs = case BS.splitAt 3 rs of
("n,,", rs') -> do
let kv = readFields rs'
(,) <$> lookup "n" kv <*> lookup "r" kv
_ -> Nothing
readServerFirstMessage :: BS.ByteString -> Maybe (BS.ByteString, BS.ByteString, Int)
readServerFirstMessage ch = do
let kv = readFields ch
(,,) <$> lookup "r" kv
<*> ((\(Right r) -> r) . B64.decode <$> lookup "s" kv)
<*> (read . BSC.unpack <$> lookup "i" kv)
readClientFinalMessage ::
BS.ByteString -> Maybe (BS.ByteString, BS.ByteString, BS.ByteString)
readClientFinalMessage rs = do
let kv = readFields rs
(,,) <$> ((\(Right r) -> r) . B64.decode <$> lookup "c" kv)
<*> lookup "r" kv
<*> ((\(Right r) -> r) . B64.decode <$> lookup "p" kv)
readServerFinalMessage :: BS.ByteString -> Maybe BS.ByteString
readServerFinalMessage = lookup "v" . readFields