/// <summary> /// Signs an element. /// </summary> /// <param name="elementToAddToSigTo"></param> /// <param name="elementToSign"></param> /// <param name="certificates"></param> public void Sign(XmlElement elementToAddToSigTo, XmlElement elementToSign, X509Certificate2Collection certificates) { ArgumentUtils.CheckNotNull(elementToAddToSigTo, "elementToAddToSigTo"); ArgumentUtils.CheckNotNull(elementToSign, "elementToSign"); CertificateUtils.CheckNotNullOrEmpty(certificates, "certificates"); IList <XmlElement> elementsToSign = new List <XmlElement>(); elementsToSign.Add(elementToSign); Sign(elementToAddToSigTo, elementsToSign, certificates); }
/// <summary> /// Encrypts an element. /// </summary> /// <param name="elementToAddEncKeysTo"></param> /// <param name="elementToEncrypt"></param> /// <param name="certificates"></param> public void Encrypt(XmlElement elementToAddEncKeysTo, XmlElement elementToEncrypt, X509Certificate2Collection certificates) { ArgumentUtils.CheckNotNull(elementToAddEncKeysTo, "elementToAddEncKeysTo"); ArgumentUtils.CheckNotNull(elementToEncrypt, "elementToEncrypt"); CertificateUtils.CheckNotNullOrEmpty(certificates, "certificates"); IList <XmlElement> elementsToEncrypt = new List <XmlElement>(); elementsToEncrypt.Add(elementToEncrypt); Encrypt(elementToAddEncKeysTo, elementsToEncrypt, certificates); }
/// <summary> /// Signs a list of elements. /// </summary> /// <param name="elementToAddToSigTo"></param> /// <param name="elementsToSign"></param> /// <param name="certificates"></param> public void Sign(XmlElement elementToAddToSigTo, IList <XmlElement> elementsToSign, X509Certificate2Collection certificates) { ArgumentUtils.CheckNotNull(elementToAddToSigTo, "elementToAddToSigTo"); ArgumentUtils.CheckNotNullNorEmpty(elementsToSign, "elementsToSign"); CertificateUtils.CheckNotNullOrEmpty(certificates, "certificates"); // Get the owner document XmlDocument containerDoc = elementToAddToSigTo.OwnerDocument; // Check each certificate has a private key foreach (X509Certificate2 cert in certificates) { if (cert.PrivateKey == null) { throw new XspException("Certificate with subject '" + cert.Subject + "' does not contain a private key"); } } // Check the 'elementsToSign' elements foreach (XmlElement elementToSign in elementsToSign) { // Check an element to sign is not the same as the element where the // signature will be added if (elementToSign == elementToAddToSigTo) { throw new XspException("Cannot add the signature to an " + "element being signed"); } // Check if all elements have the same owner document if (elementToSign.OwnerDocument != containerDoc) { throw new XspException("Element to sign must belong to the same " + "document to where the signature is being added"); } // Check the element to add the signature to is not a descendant // of an element being signed if (XmlUtils.IsDescendant(elementToSign, elementToAddToSigTo)) { throw new XspException("Element to add the signature to cannot be " + "a descendant of an element being signed"); } } // Create the reference list for signing IList <string> referenceList = new List <string>(); foreach (XmlElement elementToSign in elementsToSign) { // Check if the element has an existing 'id' attribute string referenceId = null; IList <string> elemIdValues = GetIdValues(elementToSign); if (elemIdValues.Count == 0) { // There is no 'id' element on the attribute so create one and add it // Make sure reference starts with an alpha char - 'Malformed message' error if starts with number referenceId = "Id_" + Guid.NewGuid().ToString(); XmlUtils.AddIdAttribute(elementToSign, referenceId); } else { // Set the signature reference 'id' to the existing one referenceId = elemIdValues[0]; } referenceList.Add(referenceId); } // Sign all the elements foreach (X509Certificate2 certificate in certificates) { // Create the signature for the element XmlElement signatureElem = XmlSecurityUtils.Sign( containerDoc, certificate, referenceList); // Append each created signature elementToAddToSigTo.AppendChild(signatureElem); } }
/// <summary> /// Encrypts a list of elements. /// </summary> /// <param name="elementToAddEncKeysTo"></param> /// <param name="elementsToEncrypt"></param> /// <param name="certificates"></param> /// <param name="cipherKey"></param> public void Encrypt(XmlElement elementToAddEncKeysTo, IList <XmlElement> elementsToEncrypt, X509Certificate2Collection certificates, byte[] cipherKey) { ArgumentUtils.CheckNotNull(elementToAddEncKeysTo, "elementToAddEncKeysTo"); ArgumentUtils.CheckNotNullNorEmpty(elementsToEncrypt, "elementsToEncrypt"); CertificateUtils.CheckNotNullOrEmpty(certificates, "certificates"); // Check all the elements to encrypt are not the same as the element // to add the keys to and check they belong to the same document. foreach (XmlElement elementToEncrypt in elementsToEncrypt) { if (elementToEncrypt == elementToAddEncKeysTo) { throw new XspException( "Cannot add keys to an element that is being encrypted"); } if (elementToAddEncKeysTo.OwnerDocument != elementToEncrypt.OwnerDocument) { throw new XspException( "Elements to encrypt must belong to the same document as the " + "keys element"); } if (XmlUtils.IsDescendant(elementToEncrypt, elementToAddEncKeysTo)) { throw new XspException( "Element the keys are added to cannot be a child element of an " + "element to encrypt"); } } // Get the container document XmlDocument containerDoc = elementToAddEncKeysTo.OwnerDocument; // Create a random session key RijndaelManaged sessionKey = new RijndaelManaged(); sessionKey.KeySize = 256; if (cipherKey != null) { sessionKey.Key = cipherKey; } IList <string> referenceIdList = new List <string>(); foreach (XmlElement elementToEncrypt in elementsToEncrypt) { // Generate a unique reference identifier string referenceId = "_" + Guid.NewGuid().ToString(); // Add it to the reference list referenceIdList.Add(referenceId); // Create the encrypted data EncryptedData encryptedData = XmlSecurityUtils.Encrypt( sessionKey, elementToEncrypt, referenceId); // Replace the original element with the encrypted data EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false); } foreach (X509Certificate2 certificate in certificates) { // Create the encrypted key EncryptedKey encryptedKey = XmlSecurityUtils.CreateEncryptedKey( sessionKey, certificate, referenceIdList); // Import the encrypted key element into the container document XmlNode encryptedKeyElem = containerDoc.ImportNode(encryptedKey.GetXml(), true); elementToAddEncKeysTo.AppendChild(encryptedKeyElem); } }