/// <summary>
        /// Checks the container is valid.
        /// </summary>
        /// <param name="containerDoc">Signed container.</param>
        /// <exception cref="ArgumentException">Thrown when the container is not valid.
        /// </exception>
        private void CheckSignedContainer(XmlDocument containerDoc)
        {
            // Check the document is a signed container
            if (!XmlUtils.CheckElement(containerDoc.DocumentElement, SignedPayloadElement,
                                       this.signedPayloadXmlNs))
            {
                throw new ArgumentException("Document is not a signed container");
            }

            XmlNamespaceManager namespaceManager =
                CreateXmlNamespaceManager(containerDoc);

            // Check the container has signatures
            IList <XmlElement> signatureElems = XPathUtils.GetElements(containerDoc,
                                                                       "/sp:signedPayload/sp:signatures/ds:Signature", namespaceManager);

            if (signatureElems.Count == 0)
            {
                throw new XspException("No signatures were found in the signed container");
            }

            // Check the container contains data
            if (XPathUtils.GetElement(containerDoc,
                                      "/sp:signedPayload/sp:signedPayloadData", namespaceManager) == null)
            {
                throw new XspException("No data section within the container");
            }
        }
        /// <summary>
        /// Decrypts an encrypted container Xml element, returning the payload.
        /// </summary>
        /// <param name="encryptedPayloadElem">Encrypted container to decrypt.</param>
        /// <param name="certificate">Certificate to decrypt with.</param>
        /// <returns>Decrypted payload.</returns>
        /// <exception cref="XspException">Thrown on error.</exception>
        public XmlDocument GetData(XmlElement encryptedPayloadElem,
                                   X509Certificate2 certificate)
        {
            ArgumentUtils.CheckNotNull(encryptedPayloadElem, "encryptedPayloadElem");
            ArgumentUtils.CheckNotNull(certificate, "certificate");

            // Check the root element belongs to the right namespace
            if (!XmlUtils.CheckElement(encryptedPayloadElem, EncryptedPayloadElement,
                                       this.encryptedPayloadXmlNs))
            {
                throw new ArgumentException("Document is not an encrypted container");
            }

            // Clone the source element so it is not modified
            XmlElement clonePayloadElem = XmlUtils.Clone(encryptedPayloadElem);

            // Create a namespace manager for XPath
            XmlNamespaceManager namespaceManager = CreateXmlNamespaceManager(
                clonePayloadElem.OwnerDocument);

            // Get the 'xenc:EncryptedData' element
            XmlElement encryptedDataElem = XPathUtils.GetElement(clonePayloadElem,
                                                                 "/ep:encryptedPayload/ep:encryptedPayloadData/xenc:EncryptedData",
                                                                 namespaceManager);

            if (encryptedDataElem == null)
            {
                throw new XspException("Encrypted data was not found within the container");
            }

            // Get the 'xenc:EncryptedKey' element list
            IList <XmlElement> keyElems = XPathUtils.GetElements(clonePayloadElem,
                                                                 "/ep:encryptedPayload/ep:keys/xenc:EncryptedKey", namespaceManager);

            if (keyElems.Count == 0)
            {
                throw new XspException("No encrypted keys found within the container");
            }

            // Decrypt the data
            this.encryptedProfileService.Decrypt(keyElems, encryptedDataElem,
                                                 certificate);

            // Get the payload element
            XmlElement payloadElem = XPathUtils.GetElement(clonePayloadElem,
                                                           "/ep:encryptedPayload/ep:encryptedPayloadData/*[1]", namespaceManager);

            // Return the payload element within a new Xml document
            return(XmlUtils.CreateXmlDocument(payloadElem));
        }
        /// <summary>
        /// Decrypts an encrypted container document returning the payload.
        /// </summary>
        /// <param name="encryptedPayloadDoc">Encrypted container to decrypt.</param>
        /// <param name="cipherKey">The cipher key to use to decrypt the document.</param>
        /// <returns>Decrypted payload.</returns>
        /// <exception cref="XspException">Thrown on error.</exception>
        public XmlDocument GetData(XmlDocument encryptedPayloadDoc, byte[] cipherKey)
        {
            ArgumentUtils.CheckNotNull(encryptedPayloadDoc, "encryptedPayloadDoc");
            ArgumentUtils.CheckNotNull(cipherKey, "cipherKey");

            XmlElement docElement = encryptedPayloadDoc.DocumentElement;

            // Check the root element belongs to the right namespace
            if (!XmlUtils.CheckElement(docElement, EncryptedPayloadElement,
                                       this.encryptedPayloadXmlNs))
            {
                throw new ArgumentException("Document is not an encrypted container");
            }

            // Clone the source element so it is not modified
            XmlElement clonePayloadElem = XmlUtils.Clone(docElement);

            // Create a namespace manager for XPath
            XmlNamespaceManager namespaceManager = CreateXmlNamespaceManager(
                clonePayloadElem.OwnerDocument);

            // Get the 'xenc:EncryptedData' element
            XmlElement encryptedDataElem = XPathUtils.GetElement(clonePayloadElem,
                                                                 "/ep:encryptedPayload/ep:encryptedPayloadData/xenc:EncryptedData",
                                                                 namespaceManager);

            if (encryptedDataElem == null)
            {
                throw new XspException("Encrypted data was not found within the container");
            }

            // Decrypt the element with the cipher key
            this.encryptedProfileService.Decrypt(encryptedDataElem, cipherKey);

            // Get the payload element
            XmlElement payloadElem = XPathUtils.GetElement(clonePayloadElem,
                                                           "/ep:encryptedPayload/ep:encryptedPayloadData/*[1]", namespaceManager);

            // Return the payload element within a new Xml document
            return(XmlUtils.CreateXmlDocument(payloadElem));
        }
        /// <summary>
        /// Extracts the payload from the signed payload container.
        /// </summary>
        /// <param name="containerDoc">Signed payload container.</param>
        /// <returns>Payload.</returns>
        /// <exception cref="XspException">Thrown on error.</exception>
        public XmlDocument GetData(XmlDocument containerDoc)
        {
            ArgumentUtils.CheckNotNull(containerDoc, "containerDoc");

            // Check the document is a signed container
            if (!XmlUtils.CheckElement(containerDoc.DocumentElement, SignedPayloadElement,
                                       this.signedPayloadXmlNs))
            {
                throw new ArgumentException("Document is not a signed container");
            }

            // Create an Xml namespace manager for XPathing
            XmlNamespaceManager namespaceManager = CreateXmlNamespaceManager(
                containerDoc);

            // Get the data from the container
            XmlElement payloadDataElem = XPathUtils.GetElement(containerDoc,
                                                               "/sp:signedPayload/sp:signedPayloadData/*[1]", namespaceManager);

            return(XmlUtils.CreateXmlDocument(payloadDataElem));
        }