{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} -- | -- XML Canonicalization -- -- For §6.5 module SAML2.XML.Canonical where import Control.Monad ((<=<)) import qualified Data.ByteString as BS import Data.Tree.Class (getChildren) import qualified Text.XML.HXT.Core as HXT import SAML2.XML import qualified SAML2.XML.LibXML2 as LibXML2 import qualified SAML2.XML.Schema as XS import qualified Text.XML.HXT.Arrow.Pickle.Xml.Invertible as XP -- |§6.5 data CanonicalizationAlgorithm = CanonicalXML10 { canonicalWithComments :: Bool } -- ^§6.5.1 | CanonicalXML11 { canonicalWithComments :: Bool } -- ^§6.5.2 | CanonicalXMLExcl10 { canonicalWithComments :: Bool } -- ^ deriving (Eq, Show) instance Identifiable URI CanonicalizationAlgorithm where identifier (CanonicalXML10 False) = httpURI "www.w3.org" "/TR/2001/REC-xml-c14n-20010315" "" "" identifier (CanonicalXML10 True) = httpURI "www.w3.org" "/TR/2001/REC-xml-c14n-20010315" "" "#WithComments" identifier (CanonicalXML11 False) = httpURI "www.w3.org" "/2006/12/xml-c14n11" "" "" identifier (CanonicalXML11 True) = httpURI "www.w3.org" "/2006/12/xml-c14n11" "" "#WithComments" identifier (CanonicalXMLExcl10 False) = httpURI "www.w3.org" "/2001/10/xml-exc-c14n" "" "#" identifier (CanonicalXMLExcl10 True) = httpURI "www.w3.org" "/2001/10/xml-exc-c14n" "" "#WithComments" identifiedValues = [ CanonicalXML10 False , CanonicalXML10 True , CanonicalXML11 False , CanonicalXML11 True , CanonicalXMLExcl10 False , CanonicalXMLExcl10 True ] newtype InclusiveNamespaces = InclusiveNamespaces { inclusiveNamespacesPrefixList :: XS.NMTOKENS } deriving (Eq, Show) instance XP.XmlPickler InclusiveNamespaces where xpickle = xpTrimElemNS (mkNamespace "ec" (httpURI "www.w3.org" "/2001/10/xml-exc-c14n" "" "#")) "InclusiveNamespaces" $ [XP.biCase|n <-> InclusiveNamespaces n|] XP.>$< XP.xpAttr "PrefixList" XS.xpNMTOKENS -- |Canonicalize and serialize an XML document canonicalize :: CanonicalizationAlgorithm -> Maybe InclusiveNamespaces -> Maybe String -> HXT.XmlTree -> IO BS.ByteString canonicalize a i s = LibXML2.c14n (cm a) (inclusiveNamespacesPrefixList <$> i) (canonicalWithComments a) s <=< LibXML2.fromXmlTrees . getChildren where cm CanonicalXML10{} = LibXML2.C14N_1_0 cm CanonicalXML11{} = LibXML2.C14N_1_1 cm CanonicalXMLExcl10{} = LibXML2.C14N_EXCLUSIVE_1_0