private static void Sign(XmlElement signature, IXmlLocator xmlLocator, IExternalSignature externalSignature,
List<XmlElement> references, XmlElement dsObject, KeyInfoClause keyInfo) {
XmlDocument originalDoc = xmlLocator.GetDocument();
if (signature == null)
throw new InvalidOperationException();
XmlElement signedInfo = originalDoc.CreateElement("SignedInfo", SecurityConstants.XMLDSIG_URI);
signature.AppendChild(signedInfo);
XmlElement canonicalizationMethod = originalDoc.CreateElement("CanonicalizationMethod", SecurityConstants.XMLDSIG_URI);
canonicalizationMethod.SetAttribute("Algorithm", SecurityConstants.XMLDSIG_URI_C14N);
signedInfo.AppendChild(canonicalizationMethod);
XmlElement signatureMethod = originalDoc.CreateElement("SignatureMethod", SecurityConstants.XMLDSIG_URI);
if(externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.RSA))
signatureMethod.SetAttribute("Algorithm", SecurityConstants.XMLDSIG_URI_RSA_SHA1);
else if(externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.DSA))
signatureMethod.SetAttribute("Algorithm", SecurityConstants.XMLDSIG_URI_DSA_SHA1);
signedInfo.AppendChild(signatureMethod);
foreach (XmlElement reference in references)
signedInfo.AppendChild(reference);
//if append Signature to original document upper - reference digest will be incorrect.
originalDoc.DocumentElement.AppendChild(signature);
XmlElement signedInfoDigest = (XmlElement)signedInfo.CloneNode(true);
NormalizeNamespaces(signedInfo.CreateNavigator(), signedInfoDigest.CreateNavigator());
XmlDocument signedInfoDoc = new XmlDocument(originalDoc.NameTable);
signedInfoDoc.LoadXml(signedInfoDigest.OuterXml);
byte[] byteRange = CalculateC14nByteRange(signedInfoDoc);
//Sign with ExternalSignature
String valueBase64 = Convert.ToBase64String(externalSignature.Sign(byteRange));
XmlElement signatureValue = originalDoc.CreateElement("SignatureValue", SecurityConstants.XMLDSIG_URI);
signatureValue.AppendChild(originalDoc.CreateTextNode(valueBase64));
signature.AppendChild(signatureValue);
if(keyInfo != null) {
XmlElement keyInfoElement = originalDoc.CreateElement("KeyInfo", SecurityConstants.XMLDSIG_URI);
keyInfoElement.AppendChild(originalDoc.ImportNode(keyInfo.GetXml(), true));
signature.AppendChild(keyInfoElement);
}
if (dsObject != null)
signature.AppendChild(dsObject);
xmlLocator.SetDocument(originalDoc);
}
}