/// <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)); }