wai-saml2-0.3.0.0: src/Network/Wai/SAML2/XML/Encrypted.hs
--------------------------------------------------------------------------------
-- SAML2 Middleware for WAI --
--------------------------------------------------------------------------------
-- This source code is licensed under the MIT license found in the LICENSE --
-- file in the root directory of this source tree. --
--------------------------------------------------------------------------------
-- | Types representing elements of the encrypted XML standard.
-- See https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html
module Network.Wai.SAML2.XML.Encrypted (
CipherData(..),
EncryptionMethod(..),
EncryptedKey(..),
EncryptedAssertion(..)
) where
--------------------------------------------------------------------------------
import qualified Data.Text as T
import Data.Text.Encoding
import qualified Data.ByteString as BS
import Text.XML.Cursor
import Network.Wai.SAML2.XML
import Network.Wai.SAML2.KeyInfo
--------------------------------------------------------------------------------
-- | Represents some ciphertext.
data CipherData = CipherData {
cipherValue :: !BS.ByteString
} deriving (Eq, Show)
instance FromXML CipherData where
parseXML cursor = pure CipherData{
cipherValue = encodeUtf8
$ T.concat
$ cursor
$/ element (xencName "CipherValue")
&/ content
}
--------------------------------------------------------------------------------
-- | Describes an encryption method.
data EncryptionMethod = EncryptionMethod {
-- | The name of the algorithm.
encryptionMethodAlgorithm :: !T.Text,
-- | The name of the digest algorithm, if any.
encryptionMethodDigestAlgorithm :: !(Maybe T.Text)
} deriving (Eq, Show)
instance FromXML EncryptionMethod where
parseXML cursor = pure EncryptionMethod{
encryptionMethodAlgorithm =
T.concat $ attribute "Algorithm" cursor,
encryptionMethodDigestAlgorithm =
toMaybeText $ cursor
$/ element (dsName "DigestMethod")
>=> attribute "Algorithm"
}
--------------------------------------------------------------------------------
-- | Represents an encrypted key.
data EncryptedKey = EncryptedKey {
-- | The ID of the key.
encryptedKeyId :: !T.Text,
-- | The intended recipient of the key.
encryptedKeyRecipient :: !T.Text,
-- | The method used to encrypt the key.
encryptedKeyMethod :: !EncryptionMethod,
-- | The key data.
encryptedKeyData :: !(Maybe KeyInfo),
-- | The ciphertext.
encryptedKeyCipher :: !CipherData
} deriving (Eq, Show)
instance FromXML EncryptedKey where
parseXML cursor = do
method <- oneOrFail "EncryptionMethod is required" (
cursor $/ element (xencName "EncryptionMethod")
) >>= parseXML
keyData <- case cursor $/ element (dsName "KeyInfo") of
[] -> return Nothing
(keyInfo :_) -> Just <$> parseXML keyInfo
cipher <- oneOrFail "CipherData is required" (
cursor $/ element (xencName "CipherData")
) >>= parseXML
pure EncryptedKey{
encryptedKeyId = T.concat $ attribute "Id" cursor,
encryptedKeyRecipient = T.concat $ attribute "Recipient" cursor,
encryptedKeyMethod = method,
encryptedKeyData = keyData,
encryptedKeyCipher = cipher
}
--------------------------------------------------------------------------------
-- | Represents an encrypted SAML assertion.
data EncryptedAssertion = EncryptedAssertion {
-- | Information about the encryption method used.
encryptedAssertionAlgorithm :: !EncryptionMethod,
-- | The encrypted key.
encryptedAssertionKey :: !EncryptedKey,
-- | The ciphertext.
encryptedAssertionCipher :: !CipherData
} deriving (Eq, Show)
instance FromXML EncryptedAssertion where
parseXML cursor = do
encryptedData <- oneOrFail "EncryptedData is required"
$ cursor
$/ element (xencName "EncryptedData")
algorithm <- oneOrFail "Algorithm is required"
$ encryptedData
$/ element (xencName "EncryptionMethod")
>=> parseXML
keyInfo <- oneOrFail "EncryptedKey is required" $ mconcat
[ cursor $/ element (xencName "EncryptedKey")
>=> parseXML
, cursor
$/ element (xencName "EncryptedData")
&/ element (dsName "KeyInfo")
&/ element (xencName "EncryptedKey")
>=> parseXML
]
cipher <- oneOrFail "CipherData is required"
( encryptedData
$/ element (xencName "CipherData")
) >>= parseXML
pure EncryptedAssertion{
encryptedAssertionAlgorithm = algorithm,
encryptedAssertionKey = keyInfo,
encryptedAssertionCipher = cipher
}
--------------------------------------------------------------------------------