public override object EncodeCMS(X509Certificate2 certificate, string xmlFilePath) { XmlDocument Document = new XmlDocument(); Document.PreserveWhitespace = true; XmlTextReader XmlFile = new XmlTextReader(xmlFilePath); Document.Load(XmlFile); XmlFile.Close(); XmlNodeList SignaturesList = Document.GetElementsByTagName("Signature"); // Remove existing signatures, this is not a countersigning. for (int i = 0; i < SignaturesList.Count; i++) { SignaturesList[i].ParentNode.RemoveChild(SignaturesList[i]); i--; } SignedXml SignedXml = new SignedXml(Document); SignedXml.SigningKey = certificate.PrivateKey; Reference Reference = new Reference(); Reference.Uri = ""; XmlDsigEnvelopedSignatureTransform EnvelopedSignatureTransform = new XmlDsigEnvelopedSignatureTransform(); Reference.AddTransform(EnvelopedSignatureTransform); SignedXml.AddReference(Reference); KeyInfo Key = new KeyInfo(); Key.AddClause(new KeyInfoX509Data(certificate)); SignedXml.KeyInfo = Key; SignedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement XmlDigitalSignature = SignedXml.GetXml(); return XmlDigitalSignature; }
// Sign an XML file. // This document cannot be verified unless the verifying // code has the key with which it was signed. public static void SignXml(XmlDocument xmlDoc, RSA Key) { // Check arguments. if (xmlDoc == null) throw new ArgumentException("xmlDoc"); if (Key == null) throw new ArgumentException("Key"); // Create a SignedXml object. SignedXml signedXml = new SignedXml(xmlDoc); // Add the key to the SignedXml document. signedXml.SigningKey = Key; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); }
private static string SignXml(XmlDocument unsignedXml, AsymmetricAlgorithm key) { if (unsignedXml.DocumentElement == null) { throw new ArgumentNullException("unsignedXml"); } // Create a reference to be signed. Blank == Everything var emptyReference = new Reference { Uri = "" }; // Add an enveloped transformation to the reference. var envelope = new XmlDsigEnvelopedSignatureTransform(); emptyReference.AddTransform(envelope); var signedXml = new SignedXml(unsignedXml) { SigningKey = key }; signedXml.AddReference(emptyReference); signedXml.ComputeSignature(); var digitalSignature = signedXml.GetXml(); unsignedXml.DocumentElement.AppendChild( unsignedXml.ImportNode(digitalSignature, true)); var signedXmlOut = new StringBuilder(); using (var swOut = new StringWriter(signedXmlOut)) { unsignedXml.Save(swOut); } return signedXmlOut.ToString(); }
void AddSignedXml() { // Create a SignedXml object. SignedXml signedXml = new SignedXml(this.XmlDoc); // Add the key to the SignedXml document. signedXml.SigningKey = SigningCertificate.PrivateKey; // http://stackoverflow.com/questions/13750343/net-signedxml-signing-xml-with-transform-algorithm-exc-c14n signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; // Create a reference to be signed. Reference reference = new Reference() { Uri = "#" + Id }; // Add an enveloped transformation to the reference. reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); //canonicalize reference.AddTransform(new XmlDsigExcC14NTransform()); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data keyInfoData = new KeyInfoX509Data(SigningCertificate); keyInfo.AddClause(keyInfoData); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. this.XmlDoc.DocumentElement.AppendChild(this.XmlDoc.ImportNode(xmlDigitalSignature, true)); }
public LicenseDetails ValidateLicenseXml(string xml) { var doc = new XmlDocument(); using (TextReader reader = new StringReader(xml)) { try { doc.Load(reader); } catch { throw new InvalidLicenseXmlException(); } // Validate the xml's signature var signedXml = new SignedXml(doc); var nodeList = doc.GetElementsByTagName("Signature"); if (nodeList.Count == 0) throw new LicenseSignatureMissingException(); signedXml.LoadXml((XmlElement) nodeList[0]); if (!signedXml.CheckSignature(_key)) throw new LicenseSignatureMismatchException(); } // Deserialize the xml var deserializer = new XmlSerializer(typeof(LicenseDetails)); using (TextReader reader = new StringReader(xml)) return (LicenseDetails) deserializer.Deserialize(reader); }
/// <summary> /// Creates a chain of X509Certificates given the provided XML-DSig. /// </summary> /// <param name="xmlDoc">XML-Dsig used to create the chain.</param> /// <returns>Chain of X509Certificates</returns> public static List<X509Certificate2> CertificateChain(string xmlDoc) { if (xmlDoc == null) { throw new ArgumentException("xmlDoc was null"); } var xml = XmlUtil.LoadXml(xmlDoc); var xmlNamespaces = new XmlNamespaceManager(xml.NameTable); xmlNamespaces.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); var sigElement = (XmlElement)xml.SelectSingleNode("//ds:Signature[1]", xmlNamespaces); var signature = new SignedXml(xml); signature.LoadXml(sigElement); var certificates = new List<X509Certificate2>(); foreach (var clause in signature.KeyInfo) { if (!(clause is KeyInfoX509Data)) continue; foreach (var x509Cert in ((KeyInfoX509Data)clause).Certificates) { certificates.Add((X509Certificate2)x509Cert); } } return certificates; }
// Verify the signature of an XML file against an asymmetric // algorithm and return the result. public static Boolean VerifyXml(XmlDocument Doc, RSA Key) { // Check arguments. if (Doc == null) throw new ArgumentException("Doc"); if (Key == null) throw new ArgumentException("Key"); // Create a new SignedXml object and pass it // the XML document class. SignedXml signedXml = new SignedXml(Doc); // Find the "Signature" node and create a new // XmlNodeList object. XmlNodeList nodeList = Doc.GetElementsByTagName("Signature"); // Throw an exception if no signature was found. if (nodeList.Count <= 0) { throw new CryptographicException("Verification failed: No Signature was found in the document."); } //One Sig per document if (nodeList.Count >= 2) { throw new CryptographicException("Verification failed: More that one signature was found for the document."); } // Load the first <signature> node. signedXml.LoadXml((XmlElement)nodeList[0]); // Check the signature and return the result. return signedXml.CheckSignature(Key); }
public static string Sign(string xml, X509Certificate2 certificate) { if (xml == null) throw new ArgumentNullException("xml"); if (certificate == null) throw new ArgumentNullException("certificate"); if (!certificate.HasPrivateKey) throw new ArgumentException("Certificate should have a private key", "certificate"); XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; doc.LoadXml(xml); SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey = certificate.PrivateKey; // Attach certificate KeyInfo KeyInfoX509Data keyInfoData = new KeyInfoX509Data(certificate); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(keyInfoData); signedXml.KeyInfo = keyInfo; // Attach transforms var reference = new Reference(""); reference.AddTransform(new XmlDsigEnvelopedSignatureTransform(includeComments: false)); reference.AddTransform(new XmlDsigExcC14NTransform(includeComments: false)); signedXml.AddReference(reference); // Compute signature signedXml.ComputeSignature(); var signatureElement = signedXml.GetXml(); // Add signature to bundle doc.DocumentElement.AppendChild(doc.ImportNode(signatureElement, true)); return doc.OuterXml; }
/// <summary> /// Gets the signature from an XmlDocument. /// </summary> /// <param name="xmlDocument">The source XmlDocument.</param> /// <returns>A SignedXml object representing the signature.</returns> private static SignedXml ExtractSignature(XmlDocument xmlDocument) { var signedXml = new SignedXml(xmlDocument); XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature"); signedXml.LoadXml((XmlElement)nodeList[0]); return signedXml; }
public void LoadXmlMalformed1 () { SignedXml s = new SignedXml (); XmlDocument doc = new XmlDocument (); doc.LoadXml ("<root/>"); s.LoadXml (doc.DocumentElement); }
public void LoadXmlMalformed2 () { SignedXml s = new SignedXml (); XmlDocument doc = new XmlDocument (); doc.LoadXml ("<ds:Signature xmlns:ds='http://www.w3.org/2000/09/xmldsig#'><foo/><bar/></ds:Signature>"); s.LoadXml (doc.DocumentElement); }
public static void Sign(this XmlDocument xmlDocument, X509Certificate2 cert) { if (xmlDocument == null) { throw new ArgumentNullException("xmlDocument"); } if (cert == null) { throw new ArgumentNullException("cert"); } var signedXml = new SignedXml(xmlDocument); // The transform XmlDsigExcC14NTransform and canonicalization method XmlDsigExcC14NTransformUrl is important for partially signed XML files // see: http://msdn.microsoft.com/en-us/library/system.security.cryptography.xml.signedxml.xmldsigexcc14ntransformurl(v=vs.110).aspx // The reference URI has to be set correctly to avoid assertion injections // For both, the ID/Reference and the Transform/Canonicalization see as well: // https://www.oasis-open.org/committees/download.php/35711/sstc-saml-core-errata-2.0-wd-06-diff.pdf section 5.4.2 and 5.4.3 signedXml.SigningKey = (RSACryptoServiceProvider)cert.PrivateKey; signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; var reference = new Reference { Uri = "#" + xmlDocument.DocumentElement.GetAttribute("ID") }; reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigExcC14NTransform()); signedXml.AddReference(reference); signedXml.ComputeSignature(); xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signedXml.GetXml(), true)); }
/// <summary> /// Use an X509 certificate to append a computed signature to an XML serialized Response /// </summary> /// <param name="XMLSerializedSAMLResponse"></param> /// <param name="ReferenceURI">Assertion ID from SAML Response</param> /// <param name="SigningCert">X509 Certificate for signing</param> /// <remarks>Referenced this article: /// http://www.west-wind.com/weblog/posts/2008/Feb/23/Digitally-Signing-an-XML-Document-and-Verifying-the-Signature /// </remarks> public static void AppendSignatureToXMLDocument(ref XmlDocument XMLSerializedSAMLResponse, String ReferenceURI, X509Certificate2 SigningCert) { XmlNamespaceManager ns = new XmlNamespaceManager(XMLSerializedSAMLResponse.NameTable); ns.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion"); XmlElement xeAssertion = XMLSerializedSAMLResponse.DocumentElement.SelectSingleNode("saml:Assertion", ns) as XmlElement; //SignedXml signedXML = new SignedXml(XMLSerializedSAMLResponse); SignedXml signedXML = new SignedXml(xeAssertion); signedXML.SigningKey = SigningCert.PrivateKey; signedXML.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; Reference reference = new Reference(); reference.Uri = ReferenceURI; reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigExcC14NTransform()); signedXML.AddReference(reference); signedXML.ComputeSignature(); XmlElement signature = signedXML.GetXml(); XmlElement xeResponse = XMLSerializedSAMLResponse.DocumentElement; xeResponse.AppendChild(signature); }
/// <summary> /// 验证 XML 文档的数字签名 /// </summary> /// <param name="Doc"></param> /// <param name="Key"></param> /// <returns></returns> public static Boolean VerifyXml(XmlDocument Doc, RSA Key) { // Check arguments. if (Doc == null) throw new ArgumentException("Doc"); if (Key == null) throw new ArgumentException("Key"); // 创建一个新的 SignedXml 对象,并将 XmlDocument 对象传递给它。 SignedXml signedXml = new SignedXml(Doc); // 找到 <signature> 元素,并创建新的 XmlNodeList 对象。 XmlNodeList nodeList = Doc.GetElementsByTagName("Signature"); // 如果没有签名,那么抛异常. if (nodeList.Count <= 0) { throw new CryptographicException("Verification failed: No Signature was found in the document."); } // 如果有多个签名,那么也抛异常. if (nodeList.Count >= 2) { throw new CryptographicException("Verification failed: More that one signature was found for the document."); } // 将第一个 <signature> 元素的 XML 加载到 SignedXml 对象中。 signedXml.LoadXml((XmlElement)nodeList[0]); // 使用 CheckSignature 方法和 RSA 公钥检查签名。 此方法将返回指示成功或失败的布尔值。 return signedXml.CheckSignature(Key); }
/// <summary> /// Checks if an xml element is signed by the given certificate, through /// a contained enveloped signature. /// </summary> /// <param name="xmlElement">Xml Element that should be signed</param> /// <param name="signingKeys">Signing keys to test, one should validate.</param> /// <param name="validateCertificate">Should the certificate be validated too?</param> /// <returns>True on correct signature, false on missing signature</returns> /// <exception cref="InvalidSignatureException">If the data has /// been tampered with or is not valid according to the SAML spec.</exception> public static bool IsSignedByAny( this XmlElement xmlElement, IEnumerable<SecurityKeyIdentifierClause> signingKeys, bool validateCertificate) { if (xmlElement == null) { throw new ArgumentNullException(nameof(xmlElement)); } var signedXml = new SignedXml(xmlElement); var signatureElement = xmlElement["Signature", SignedXml.XmlDsigNamespaceUrl]; if (signatureElement == null) { return false; } signedXml.LoadXml(signatureElement); ValidateSignedInfo(signedXml, xmlElement); VerifySignature(signingKeys, signedXml, signatureElement, validateCertificate); return true; }
/// <summary> /// Verifies the digital signature. /// </summary> /// <param name="digitalSignature"> The XML Digital Signature.</param> /// <param name="publicKey"> The RSA public key.</param> /// <returns> Returns true if valid, else false.</returns> public static bool VerifyDigitalSignature(XmlTextReader digitalSignature, RSA publicKey) { bool valid = false; try { // Load license file into XmlDocument XmlDocument doc = new XmlDocument(); doc.Load(digitalSignature); // Load Signature Element SignedXml verifier = new SignedXml(doc); verifier.LoadXml(doc.GetElementsByTagName("Signature")[0] as XmlElement); // Validate license. if ( verifier.CheckSignature(publicKey) ) { valid = true; } else { valid = false; } } catch { valid = false; } return valid; }
public void VerifyXml(string xml) { var doc = LoadXmlDoc(xml); using (var rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(publicKey); var nsMgr = new XmlNamespaceManager(doc.NameTable); nsMgr.AddNamespace("sig", "http://www.w3.org/2000/09/xmldsig#"); var signedXml = new SignedXml(doc); var signature = (XmlElement)doc.SelectSingleNode("//sig:Signature", nsMgr); if (signature == null) { throw new Exception("Xml is invalid as it has no XML signature"); } signedXml.LoadXml(signature); if (!signedXml.CheckSignature(rsa)) { throw new Exception("Xml is invalid as it failed signature check."); } } }
public static void Sign(this XmlDocument xmlDocument, X509Certificate2 cert) { if(xmlDocument == null) { throw new ArgumentNullException("xmlDocument"); } if (cert == null) { throw new ArgumentNullException("cert"); } var signedXml = new SignedXml(xmlDocument); signedXml.SigningKey = (RSACryptoServiceProvider)cert.PrivateKey; var reference = new Reference(); reference.Uri = ""; reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); signedXml.AddReference(reference); signedXml.ComputeSignature(); xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signedXml.GetXml(), true)); }
/// <summary> /// Adds a digital signature to the outgoing request message, before sending it to Acquirer. /// </summary> /// <param name="requestXml"> /// The unsigned request XML message. /// </param> /// <returns> /// The request message, including digital signature. /// </returns> public string SignRequestXml(XDocument requestXml) { XmlDocument document = ToXmlDocument(requestXml); RSACryptoServiceProvider key = ExtractPrivateKeyFrom(acceptantPrivateCertificate); var signedXml = new SignedXml(document) { SigningKey = key }; signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#"; // Add a signing reference, the uri is empty and so the whole document is signed. var reference = new Reference { DigestMethod = @"http://www.w3.org/2001/04/xmlenc#sha256" }; reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.Uri = ""; signedXml.AddReference(reference); // Add the certificate as key info. Because of this, the certificate // with the public key will be added in the signature part. var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoName(acceptantPrivateCertificate.Thumbprint)); signedXml.KeyInfo = keyInfo; // Generate the signature. signedXml.ComputeSignature(); XmlElement xmlSignature = signedXml.GetXml(); document.DocumentElement.AppendChild(document.ImportNode(xmlSignature, true)); // Check that outgoing signature is valid. Private certificate also contains public part. VerifyDocumentSignature(document, acceptantPrivateCertificate); return GetContentsFrom(document); }
// /// <summary> // /// Signs a license. // /// </summary> // /// <param name="unsignedLicense"> The unsigned license stream.</param> // /// <param name="keyPair"> The stream containing the private key file.</param> // /// <param name="output"> The output stream containing the new signed license.</param> // internal void SignLicense(XmlTextReader unsignedLicense, Stream keyPair, Stream output) // { // try // { // // setup the document to sign // XmlDocument licenseDocument = new XmlDocument(); // licenseDocument.Load(unsignedLicense); // // // read in the public key // RSA signingKey = new RSACryptoServiceProvider(); // using(StreamReader reader = new StreamReader(keyPair)) // { // signingKey.FromXmlString(reader.ReadLine()); // } // // // now sign the document // SignedXml signer = new SignedXml(licenseDocument); // signer.SigningKey = signingKey; // // // create a reference to the root of the document // Reference orderRef = new Reference(""); // orderRef.AddTransform(new XmlDsigEnvelopedSignatureTransform()); // signer.AddReference(orderRef); // // // add transforms that only select the order items, type, and // // compute the signature, and add it to the document // signer.ComputeSignature(); // licenseDocument.DocumentElement.AppendChild(signer.GetXml()); // // licenseDocument.Save(output); // } // catch // { // throw; // } // } /// <summary> /// Signs the XmlDocument. /// </summary> /// <param name="document"> The XmlDocument to sign.</param> /// <param name="signingKey"> The signing key.</param> /// <returns> A signed XmlDocument.</returns> internal XmlDocument SignXmlDocument(XmlDocument document, RSA signingKey) { try { // // setup the document to sign // XmlDocument licenseDocument = new XmlDocument(); // licenseDocument.Load(unsignedLicense); // now sign the document SignedXml signer = new SignedXml(document); signer.SigningKey = signingKey; // create a reference to the root of the document Reference reference = new Reference(""); reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); signer.AddReference(reference); // compute the signature, and add it to the document signer.ComputeSignature(); document.DocumentElement.AppendChild(signer.GetXml()); return document; } catch { throw; } }
private static XmlDocument SignXml() { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.Load(".\\certificates\\samlRequestTemplate.xml"); X509Certificate2 certificate = CertificateHelper.GetCertificate(".\\certificates\\HuaweiCA.p12", "Pr0d1234"); //AsymmetricAlgorithm key = certificate.PrivateKey; AsymmetricAlgorithm key = certificate.PrivateKey; XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable); ns.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion"); ns.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol"); XmlElement issuerNode = (XmlElement)xmlDoc.DocumentElement.SelectSingleNode("saml:Issuer", ns); SignedXml signedXml = new SignedXml(xmlDoc.DocumentElement); signedXml.SigningKey = key; signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; KeyInfo keyInfo = new KeyInfo(); //XmlDocument keyDoc = new XmlDocument(); //keyDoc.LoadXml(certificate.PublicKey.Key.ToXmlString(false)); //keyInfo.LoadXml(keyDoc.DocumentElement); keyInfo.AddClause(new KeyInfoX509Data(certificate)); signedXml.KeyInfo = keyInfo; string refId = xmlDoc.DocumentElement.GetAttribute("ID"); Reference reference = new Reference(); reference.Uri = "#" + refId; XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigExcC14NTransform env2 = new XmlDsigExcC14NTransform(); env2.InclusiveNamespacesPrefixList = "#default code ds kind rw saml samlp typens"; reference.AddTransform(env2); signedXml.AddReference(reference); signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); xmlDoc.DocumentElement.InsertAfter(xmlDoc.ImportNode(xmlDigitalSignature, true), issuerNode); //xmlDoc.NameTable.Add("samlp"); //XmlElement nameIDPolicyElem = xmlDoc.CreateElement("samlp", "NameIDPolicy", "urn:oasis:names:tc:SAML:2.0:protocol"); //nameIDPolicyElem.SetAttribute("AllowCreate", "False"); //xmlDoc.DocumentElement.AppendChild(nameIDPolicyElem); xmlDoc.Save("samleRequestCSharp.xml"); return xmlDoc; }
public void assinaturaXMLCancel() { try { Reference reference = new Reference(); SignedXml docXML = new SignedXml(xmlDoc); try { docXML.SigningKey = cert.PrivateKey; XmlAttributeCollection uri = xmlDoc.GetElementsByTagName("infEvento").Item(0).Attributes; foreach (XmlAttribute atributo in uri) { if (atributo.Name == "Id") reference.Uri = "#" + atributo.InnerText; } } catch (Exception ex) { Utils.Logger.getInstance.error(ex); throw new Exception("Erro em Assinatura p1" + ex.Message); } XmlDsigEnvelopedSignatureTransform envelopedSigntature = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envelopedSigntature); XmlDsigC14NTransform c14Transform = new XmlDsigC14NTransform(); reference.AddTransform(c14Transform); docXML.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); docXML.KeyInfo = keyInfo; docXML.ComputeSignature(); XmlElement xmlDigitalSignature = docXML.GetXml(); foreach (var _nfe in xmlDoc.GetElementsByTagName("evento").Cast<XmlElement>()) { _nfe.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); } } catch (Exception ex) { Utils.Logger.getInstance.error(ex); throw new Exception("Erro preparando Assinatura Digital\n" + ex.Message); } //xmlDoc.PreserveWhitespace = true; }
public bool IsValid() { XmlNamespaceManager manager = new XmlNamespaceManager(XmlDoc.NameTable); manager.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); XmlNodeList nodeList = XmlDoc.SelectNodes("//ds:Signature", manager); SignedXml signedXml = new SignedXml(XmlDoc); signedXml.LoadXml((XmlElement)nodeList[0]); return signedXml.CheckSignature(DecrypingCertificate, true); }
public void Constructor_XmlDocument () { XmlDocument doc = new XmlDocument (); doc.LoadXml (signature); XmlNodeList xnl = doc.GetElementsByTagName ("Signature", SignedXml.XmlDsigNamespaceUrl); XmlElement xel = (XmlElement) xnl [0]; SignedXml sx = new SignedXml (doc); sx.LoadXml (doc.DocumentElement); Assert.IsTrue (sx.CheckSignature (), "CheckSignature"); }
protected OpensignAbstractSignature(XmlDocument doc) { Doc = doc; var xmlNamespaces = new XmlNamespaceManager(Doc.NameTable); xmlNamespaces.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); SigElement = (XmlElement)Doc.SelectSingleNode("//ds:Signature[1]", xmlNamespaces); Signature = new SignedXml(Doc); Valid = IsValidSignature(); }
public XmlDocument assinaturaXmlEnviar(XmlDocument _xml) { XmlDocument xmlDocAss = _xml; try { if (cert == null) throw new Exception("Nao foi encontrado o certificado: " + config.configNFCe.NomeCertificadoDigital); Reference reference = new Reference(); SignedXml docXML = new SignedXml(xmlDocAss); docXML.SigningKey = cert.PrivateKey; XmlAttributeCollection uri = xmlDocAss.GetElementsByTagName("infNFe").Item(0).Attributes; foreach (XmlAttribute atributo in uri) { if (atributo.Name == "Id") reference.Uri = "#" + atributo.InnerText; } XmlDsigEnvelopedSignatureTransform envelopedSigntature = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envelopedSigntature); XmlDsigC14NTransform c14Transform = new XmlDsigC14NTransform(); reference.AddTransform(c14Transform); docXML.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); docXML.KeyInfo = keyInfo; docXML.ComputeSignature(); XmlElement xmlDigitalSignature = docXML.GetXml(); foreach (var _nfe in xmlDocAss.GetElementsByTagName("NFe").Cast<XmlElement>()) _nfe.AppendChild(xmlDocAss.ImportNode(xmlDigitalSignature, true)); xmlDocAss.PreserveWhitespace = true; return xmlDocAss; } catch (Exception e) { Utils.Logger.getInstance.error(e); return null; throw new Exception(e.ToString()); } }
public static Boolean CheckSignedXmlDocument(Stream sourceXmlFile) { // Carico il documento XML XmlDocument doc = new XmlDocument(); doc.Load(sourceXmlFile); // Verifico la firma SignedXml sigs = new SignedXml(doc); XmlNodeList sigElems = doc.GetElementsByTagName("Signature"); sigs.LoadXml((XmlElement)sigElems[0]); return (sigs.CheckSignature()); }
/// <summary> /// Validate script XML signature /// </summary> /// <param name="signedXml">Signed XML</param> /// <returns>true if signature is valid</returns> public virtual bool VerifyXmlSignature(SignedXml signedXml) { bool valid = false; foreach (var k in signedXml.KeyInfo) { var kv = k as RSAKeyValue; if (kv != null) { var rsa = new RSACryptoServiceProvider(); var key = Assembly.GetExecutingAssembly().GetName().GetPublicKey(); if (key == null || key.Length < 12) return false; // here is a trick: the public key in assembly file has a 12-byte header at the beginning. // We strip it - and the remaining bytes can be now imported by RSACryptoServiceProvider class var tmpKey = new byte[key.Length - 12]; Array.Copy(key, 12, tmpKey, 0, tmpKey.Length); rsa.ImportCspBlob(tmpKey); valid = signedXml.CheckSignature(rsa); if (!valid) break; continue; } var ki = k as KeyInfoX509Data; if (ki != null) { if (ki.Certificates == null) valid = false; else foreach (X509Certificate2 cert in ki.Certificates) { // Verify that certificate is trusted for code signing X509ChainPolicy pol = new X509ChainPolicy(); pol.RevocationMode = X509RevocationMode.NoCheck; pol.VerificationFlags = X509VerificationFlags.IgnoreEndRevocationUnknown | X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown | X509VerificationFlags.IgnoreRootRevocationUnknown; pol.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.3")); X509Chain chain = new X509Chain(true); chain.ChainPolicy = pol; if (chain.Build(cert)) valid = signedXml.CheckSignature(cert, true); if (!valid) break; } if (!valid) break; continue; } } return valid; }
public string SignXml(XDocument xml) { using (MemoryStream streamIn = new MemoryStream()) { xml.Save(streamIn); streamIn.Position = 0; // var rsaKey = (RSACryptoServiceProvider)_privateCertificate.PrivateKey; // Create rsa crypto provider from private key contained in certificate, weirdest cast ever!; // string sCertFileLocation = @"C:\plugins\idealtest\bin\Debug\certficate.pfx"; // X509Certificate2 certificate = new X509Certificate2(sCertFileLocation, "D3M@ast3rsR0cks"); RSA rsaKey = (RSACryptoServiceProvider)_privateCertificate.PrivateKey; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.Load(streamIn); SignedXml signedXml = new SignedXml(xmlDoc); signedXml.SigningKey = rsaKey; Reference reference = new Reference(); reference.Uri = ""; XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); signedXml.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); KeyInfoName kin = new KeyInfoName(); kin.Value = _privateCertificate.Thumbprint; keyInfo.AddClause(kin); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); using (MemoryStream sout = new MemoryStream()) { xmlDoc.Save(sout); sout.Position = 0; using (StreamReader reader = new StreamReader(sout)) { string xmlOut = reader.ReadToEnd(); return xmlOut; } } } }
static void Main(string[] args) { X509Store store = new X509Store("MY", StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; var x509 = collection.Find(X509FindType.FindBySubjectName, "note-oberdan.pca.com.br", true); X509Certificate2 cert = x509[0]; RSA rsa = (RSA)cert.PrivateKey; XmlDocument doc = new XmlDocument(); doc.InnerXml = "<teste vl=\"1\"></teste>"; SignedXml SignedDocument = new SignedXml(); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new System.Security.Cryptography.Xml.KeyInfoX509Data(cert)); SignedDocument = new System.Security.Cryptography.Xml.SignedXml(doc); //Seta chaves SignedDocument.SigningKey = rsa; SignedDocument.KeyInfo = keyInfo; //Cria referencia Reference reference = new Reference(); reference.Uri = String.Empty; //Adiciona transformacao a referencia reference.AddTransform(new System.Security.Cryptography.Xml.XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new System.Security.Cryptography.Xml.XmlDsigC14NTransform(false)); //Adiciona referencia ao xml SignedDocument.AddReference(reference); //Calcula Assinatura SignedDocument.ComputeSignature(); //Pega representação da assinatura XmlElement xmlDigitalSignature = SignedDocument.GetXml(); //Adiciona ao doc XML doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); doc.Save(@"C:\testes\ExemploAssinaturaXML\ExemploAssinaturaXML\xmlAssinado3.xml"); }
internal static XmlElement GetXmlDigitalSignature(XmlDocument doc, AsymmetricAlgorithm key) { if(IsDebugEnabled) log.Debug("암호화된 Xml 문서를 만듭니다..."); var signedXml = new SignedXml(doc) { SigningKey = key }; var reference = new Reference { Uri = string.Empty }; reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); signedXml.AddReference(reference); signedXml.ComputeSignature(); return signedXml.GetXml(); }
/// <include file='doc\KeyInfo.uex' path='docs/doc[@for="KeyInfoX509Data.LoadXml"]/*' /> public override void LoadXml(XmlElement element) { int iNumNodes = 0; // Guard against nulls if (element == null) { throw new ArgumentNullException("element"); } XmlNodeList x509IssuerSerialNodes = element.GetElementsByTagName("X509IssuerSerial", SignedXml.XmlDsigNamespaceUrl); XmlNodeList x509SKINodes = element.GetElementsByTagName("X509SKI", SignedXml.XmlDsigNamespaceUrl); XmlNodeList x509SubjectNameNodes = element.GetElementsByTagName("X509SubjectName", SignedXml.XmlDsigNamespaceUrl); XmlNodeList x509CertificateNodes = element.GetElementsByTagName("X509Certificate", SignedXml.XmlDsigNamespaceUrl); XmlNodeList x509CRLNodes = element.GetElementsByTagName("X509CRL", SignedXml.XmlDsigNamespaceUrl); iNumNodes += x509IssuerSerialNodes.Count; iNumNodes += x509SKINodes.Count; iNumNodes += x509SubjectNameNodes.Count; iNumNodes += x509CertificateNodes.Count; if ((x509CRLNodes.Count != 0 && iNumNodes != 0) || (x509CRLNodes.Count == 0 && iNumNodes == 0)) // Bad X509Data tag, or Empty tag { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "X509Data"); } if (x509CRLNodes.Count > 1) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "X509Data"); } // Flush anything in the lists Clear(); if (x509CRLNodes.Count != 0) { m_CRL = Convert.FromBase64String(SignedXml.DiscardWhiteSpaces(x509CRLNodes.Item(0).InnerText)); return; } if (x509IssuerSerialNodes != null) { foreach (XmlNode node in x509IssuerSerialNodes) { XmlNodeList elem = ((XmlNode)node).ChildNodes; if (elem == null || elem.Count < 2) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "X509IssuerSerial"); } string strIssuerName = null; string strSerialNumber = null; foreach (XmlNode node1 in elem) { if (node1.Name.Equals("X509IssuerName")) { strIssuerName = node1.InnerText; } if (node1.Name.Equals("X509SerialNumber")) { strSerialNumber = node1.InnerText; } } AddIssuerSerial(strIssuerName, strSerialNumber); } } if (x509SKINodes != null) { foreach (XmlNode node in x509SKINodes) { string strSKI = node.InnerText; AddSubjectKeyId(Convert.FromBase64String(SignedXml.DiscardWhiteSpaces(strSKI))); } } if (x509SubjectNameNodes != null) { foreach (XmlNode node in x509SubjectNameNodes) { AddSubjectName(node.InnerText); } } if (x509CertificateNodes != null) { foreach (XmlNode node in x509CertificateNodes) { AddCertificate(new X509Certificate(Convert.FromBase64String(SignedXml.DiscardWhiteSpaces(node.InnerText)))); } } }
/// <include file='doc\Reference.uex' path='docs/doc[@for="Reference.LoadXml"]/*' /> public void LoadXml(XmlElement value) { // Guard against nulls if (value == null) { throw new ArgumentNullException("value"); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); // cache the Xml m_cachedXml = value; m_originalNode = value; m_strId = value.GetAttribute("Id"); m_strUri = value.GetAttribute("URI"); m_strType = value.GetAttribute("Type"); // Transforms m_transformChain = new TransformChain(); XmlNodeList transformsNodes = value.SelectNodes("ds:Transforms", nsm); if (transformsNodes.Count != 0) { XmlElement transformsElement = (XmlElement)transformsNodes.Item(0); XmlNodeList transformNodes = transformsElement.SelectNodes("ds:Transform", nsm); if (transformNodes.Count == 0) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Transforms"); } for (int i = 0; i < transformNodes.Count; ++i) { XmlElement transformElement = (XmlElement)transformNodes.Item(i); String strAlgorithm = transformElement.GetAttribute("Algorithm"); Transform transform = (Transform)CryptoConfig.CreateFromName(strAlgorithm); if (transform == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_UnknownTransform")); } // Hack! this is done to get around the lack of here() function support in XPath if (transform is XmlDsigEnvelopedSignatureTransform) { // Walk back to the Signature tag. Find the nearest signature ancestor // Signature-->SignedInfo-->Reference-->Transforms-->Transform XmlNode signatureTag = transformElement.SelectSingleNode("ancestor::ds:Signature[1]", nsm); XmlNodeList signatureList = transformElement.SelectNodes("//ds:Signature", nsm); if (signatureList != null) { int position = 0; foreach (XmlNode node in signatureList) { position++; if (node == signatureTag) { ((XmlDsigEnvelopedSignatureTransform)transform).SignaturePosition = position; break; } } } } // let the transform read the children of the transformElement for data transform.LoadInnerXml(transformElement.ChildNodes); AddTransform(transform); } } // DigestMethod XmlNodeList digestMethodNodes = value.SelectNodes("ds:DigestMethod", nsm); if (digestMethodNodes.Count == 0) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference/DigestMethod"); } XmlElement digestMethodElement = (XmlElement)digestMethodNodes.Item(0); m_strDigestMethod = digestMethodElement.GetAttribute("Algorithm"); // DigestValue XmlNodeList digestValueNodes = value.SelectNodes("ds:DigestValue", nsm); if (digestValueNodes.Count == 0) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference/DigestValue"); } XmlElement digestValueElement = (XmlElement)digestValueNodes.Item(0); m_rgbDigestValue = Convert.FromBase64String(SignedXml.DiscardWhiteSpaces(digestValueElement.InnerText)); }
// What we want to do is pump the input throug the TransformChain and then // hash the output of the chain // document is the document context for resolving relative references internal byte[] CalculateHashValue(XmlDocument document, CanonicalXmlNodeList refList) { // refList is a list of elements that might be targets of references // Now's the time to create our hashing algorithm m_hashAlgorithm = (HashAlgorithm)CryptoConfig.CreateFromName(DigestMethod); if (m_hashAlgorithm == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_CreateHashAlgorithmFailed")); } string strBaseUri = (document == null ? null : document.BaseURI); // For interop w/ Petteri & IBM -- may not be required by the spec //if (m_transforms.Count == 0) { //if (DataObject != null && DataObject.Data != null) { //AddTransform(new W3cCanonicalization()); //} //} // Let's go get the target. Stream hashInputStream; WebRequest theRequest = null; WebResponse theResponse = null; Stream inputStream = null; XmlResolver resolver = null; switch (m_refTargetType) { case ReferenceTargetType.Stream: // This is the easiest case. We already have a stream, so just pump it through // the TransformChain resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream((Stream)m_refTarget, resolver, strBaseUri); break; case ReferenceTargetType.UriReference: // Second-easiest case -- dereference the URI & pump through the TransformChain // handle the special cases where the URI is null (meaning whole doc) // or the URI is just a fragment (meaning a reference to an embedded Object) if (m_strUri == "") { // This is the self-referential case. // The Enveloped Signature does not discard comments as per spec; those will be omitted during the transform chain process // First, check that we have a document context. if (document == null) { throw new CryptographicException(String.Format(SecurityResources.GetResourceString("Cryptography_Xml_SelfReferenceRequiresContext"), m_strUri)); } // Normalize the containing document resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); XmlDocument docWithNoComments = CanonicalXml.DiscardComments(SignedXml.PreProcessDocumentInput(document, resolver, strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(docWithNoComments, resolver, strBaseUri); } else if (m_strUri[0] == '#') { // If we get here, then we are constructing a Reference to an embedded DataObject // referenced by an Id= attribute. Go find the relevant object String idref = m_strUri.Substring(1); bool bDiscardComments = true; // Deal with XPointer of types #xpointer(/) and #xpointer(id("ID")). Other XPointer support isn't handled here and is anyway optional if (idref == "xpointer(/)") { // This is a self referencial case if (document == null) { throw new CryptographicException(String.Format(SecurityResources.GetResourceString("Cryptography_Xml_SelfReferenceRequiresContext"), m_strUri)); } // We should not discard comments here!!! resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(SignedXml.PreProcessDocumentInput(document, resolver, strBaseUri), resolver, strBaseUri); goto end; } else if (idref.StartsWith("xpointer(id(")) { int startId = idref.IndexOf("id("); int endId = idref.IndexOf(")"); if (endId < 0 || endId < startId + 3) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidReference")); } idref = idref.Substring(startId + 3, endId - startId - 3); idref = idref.Replace("\'", ""); idref = idref.Replace("\"", ""); bDiscardComments = false; } XmlElement elem = m_signedXml.GetIdElement(document, idref); if (elem == null) { // Go throw the referenced items passed in if (refList != null) { foreach (XmlNode node in refList) { XmlElement tempElem = node as XmlElement; if ((tempElem != null) && (tempElem.HasAttribute("Id")) && (tempElem.GetAttribute("Id").Equals(idref))) { elem = tempElem; break; } } } } if (elem == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidReference")); } // Add the propagated attributes, clone the element first XmlElement elemClone = elem.Clone() as XmlElement; if (m_namespaces != null) { foreach (XmlNode attrib in m_namespaces) { string name = ((attrib.Prefix != String.Empty) ? attrib.Prefix + ":" + attrib.LocalName : attrib.LocalName); // Skip the attribute if one with the same qualified name already exists if (elemClone.HasAttribute(name) || (name.Equals("xmlns") && elemClone.NamespaceURI != String.Empty)) { continue; } XmlAttribute nsattrib = (XmlAttribute)elemClone.OwnerDocument.CreateAttribute(name); nsattrib.Value = attrib.Value; elemClone.SetAttributeNode(nsattrib); } } if (bDiscardComments) { // We should discard comments before going into the transform chain resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); XmlDocument docWithNoComments = CanonicalXml.DiscardComments(SignedXml.PreProcessElementInput(elemClone, resolver, strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(docWithNoComments, resolver, strBaseUri); } else { // This is an XPointer reference, do not discard comments!!! resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(SignedXml.PreProcessElementInput(elemClone, resolver, strBaseUri), resolver, strBaseUri); } } else { theRequest = WebRequest.Create(m_strUri); if (theRequest == null) { goto default; } theResponse = theRequest.GetResponse(); if (theResponse == null) { goto default; } inputStream = theResponse.GetResponseStream(); if (inputStream == null) { goto default; } resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), m_strUri)); hashInputStream = m_transformChain.TransformToOctetStream(inputStream, resolver, m_strUri); } break; case ReferenceTargetType.XmlElement: // We need to create a DocumentNavigator out of the XmlElement resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(SignedXml.PreProcessElementInput((XmlElement)m_refTarget, resolver, strBaseUri), resolver, strBaseUri); break; default: throw new CryptographicException(); } end: // Compute the new hash value byte[] hashval = m_hashAlgorithm.ComputeHash(hashInputStream); // Close the response to free resources, before returning if (theResponse != null) { theResponse.Close(); } if (inputStream != null) { inputStream.Close(); } return(hashval); }
public void LoadXml(XmlElement value) { if (value is null) { throw new ArgumentNullException(nameof(value)); } _id = Utils.GetAttribute(value, "Id", SignedXml.XmlDsigNamespaceUrl); _uri = Utils.GetAttribute(value, "URI", SignedXml.XmlDsigNamespaceUrl); _type = Utils.GetAttribute(value, "Type", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(value, new string[] { "Id", "URI", "Type" })) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference"); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); // Transforms bool hasTransforms = false; TransformChain = new TransformChain(); XmlNodeList transformsNodes = value.SelectNodes("ds:Transforms", nsm); if (transformsNodes != null && transformsNodes.Count != 0) { if (transformsNodes.Count > 1) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } hasTransforms = true; XmlElement transformsElement = transformsNodes[0] as XmlElement; if (!Utils.VerifyAttributes(transformsElement, (string[])null)) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } XmlNodeList transformNodes = transformsElement.SelectNodes("ds:Transform", nsm); if (transformNodes != null) { if (transformNodes.Count != transformsElement.SelectNodes("*").Count) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } if (transformNodes.Count > Utils.MaxTransformsPerReference) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } foreach (XmlNode transformNode in transformNodes) { XmlElement transformElement = transformNode as XmlElement; string algorithm = Utils.GetAttribute(transformElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); if (algorithm == null || !Utils.VerifyAttributes(transformElement, "Algorithm")) { throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform); } Transform transform = CryptoHelpers.CreateFromName <Transform>(algorithm); if (transform == null) { throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform); } AddTransform(transform); // let the transform read the children of the transformElement for data transform.LoadInnerXml(transformElement.ChildNodes); // Hack! this is done to get around the lack of here() function support in XPath if (transform is XmlDsigEnvelopedSignatureTransform && _uri != null && (_uri.Length == 0 || _uri[0] == '#')) { // Walk back to the Signature tag. Find the nearest signature ancestor // Signature-->SignedInfo-->Reference-->Transforms-->Transform XmlNode signatureTag = transformElement.SelectSingleNode("ancestor::ds:Signature[1]", nsm); // Resolve the reference to get starting point for position calculation. XmlNode referenceTarget = _uri.Length == 0 ? transformElement.OwnerDocument : SignedXml.GetIdElement(transformElement.OwnerDocument, Utils.GetIdFromLocalUri(_uri, out bool _)); XmlNodeList signatureList = referenceTarget?.SelectNodes(".//ds:Signature", nsm); if (signatureList != null) { int position = 0; foreach (XmlNode node in signatureList) { position++; if (node == signatureTag) { ((XmlDsigEnvelopedSignatureTransform)transform).SignaturePosition = position; break; } } } } } } } // DigestMethod XmlNodeList digestMethodNodes = value.SelectNodes("ds:DigestMethod", nsm); if (digestMethodNodes == null || digestMethodNodes.Count == 0 || digestMethodNodes.Count > 1) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod"); } XmlElement digestMethodElement = digestMethodNodes[0] as XmlElement; _digestMethod = Utils.GetAttribute(digestMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); if (_digestMethod == null || !Utils.VerifyAttributes(digestMethodElement, "Algorithm")) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod"); } // DigestValue XmlNodeList digestValueNodes = value.SelectNodes("ds:DigestValue", nsm); if (digestValueNodes == null || digestValueNodes.Count == 0 || digestValueNodes.Count > 1) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestValue"); } XmlElement digestValueElement = digestValueNodes[0] as XmlElement; _digestValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(digestValueElement.InnerText)); if (!Utils.VerifyAttributes(digestValueElement, (string[])null)) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestValue"); } // Verify that there aren't any extra nodes that aren't allowed int expectedChildNodeCount = hasTransforms ? 3 : 2; if (value.SelectNodes("*").Count != expectedChildNodeCount) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference"); } // cache the Xml _cachedXml = value; }
// The goal behind this method is to pump the input stream through the transforms and get back something that // can be hashed internal Stream TransformToOctetStream(Object inputObject, Type inputType, XmlResolver resolver, string strBaseUri) { Object currentInput = inputObject; foreach (Object obj in m_transforms) { Transform transform = obj as Transform; if (transform.AcceptsType(currentInput.GetType())) { //in this case, no translation necessary, pump it through transform.Resolver = resolver; transform.BaseURI = strBaseUri; transform.LoadInput(currentInput); currentInput = transform.GetOutput(); } else { // We need translation // For now, we just know about Stream->{XmlNodeList,XmlDocument} and {XmlNodeList,XmlDocument}->Stream if (currentInput is Stream) { if (transform.AcceptsType(typeof(XmlDocument))) { XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; XmlValidatingReader valReader = SignedXml.PreProcessStreamInput((Stream)currentInput, resolver, strBaseUri); doc.Load(valReader); transform.LoadInput(doc); currentInput = transform.GetOutput(); continue; } else { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); } } if (currentInput is XmlNodeList) { if (transform.AcceptsType(typeof(Stream))) { CanonicalXml c14n = new CanonicalXml((XmlNodeList)currentInput, false); MemoryStream ms = new MemoryStream(c14n.GetBytes()); transform.LoadInput((Stream)ms); currentInput = transform.GetOutput(); continue; } else { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); } } if (currentInput is XmlDocument) { if (transform.AcceptsType(typeof(Stream))) { CanonicalXml c14n = new CanonicalXml((XmlDocument)currentInput); MemoryStream ms = new MemoryStream(c14n.GetBytes()); transform.LoadInput((Stream)ms); currentInput = transform.GetOutput(); continue; } else { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); } } throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); } } // Final processing, either we already have a stream or have to canonicalize if (currentInput is Stream) { return(currentInput as Stream); } if (currentInput is XmlNodeList) { CanonicalXml c14n = new CanonicalXml((XmlNodeList)currentInput, false); MemoryStream ms = new MemoryStream(c14n.GetBytes()); return(ms); } if (currentInput is XmlDocument) { CanonicalXml c14n = new CanonicalXml((XmlDocument)currentInput); MemoryStream ms = new MemoryStream(c14n.GetBytes()); return(ms); } throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); }
// // public virtual methods // // This describes how the application wants to associate id references to elements public virtual XmlElement GetIdElement(XmlDocument document, string idValue) { return(SignedXml.DefaultGetIdElement(document, idValue)); }
internal byte[] CalculateHashValue(XmlDocument document, CanonicalXmlNodeList refList) { // refList is a list of elements that might be targets of references // Now's the time to create our hashing algorithm _hashAlgorithm = CryptoHelpers.CreateFromName <HashAlgorithm>(_digestMethod); if (_hashAlgorithm == null) { throw new CryptographicException(SR.Cryptography_Xml_CreateHashAlgorithmFailed); } // Let's go get the target. string baseUri = (document == null ? System.Environment.CurrentDirectory + "\\" : document.BaseURI); Stream hashInputStream = null; WebResponse response = null; Stream inputStream = null; XmlResolver resolver = null; byte[] hashval = null; try { switch (_refTargetType) { case ReferenceTargetType.Stream: // This is the easiest case. We already have a stream, so just pump it through the TransformChain resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream((Stream)_refTarget, resolver, baseUri); break; case ReferenceTargetType.UriReference: // Second-easiest case -- dereference the URI & pump through the TransformChain // handle the special cases where the URI is null (meaning whole doc) // or the URI is just a fragment (meaning a reference to an embedded Object) if (_uri == null) { // We need to create a DocumentNavigator out of the XmlElement resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); // In the case of a Uri-less reference, we will simply pass null to the transform chain. // The first transform in the chain is expected to know how to retrieve the data to hash. hashInputStream = TransformChain.TransformToOctetStream((Stream)null, resolver, baseUri); } else if (_uri.Length == 0) { // This is the self-referential case. First, check that we have a document context. // The Enveloped Signature does not discard comments as per spec; those will be omitted during the transform chain process if (document == null) { throw new CryptographicException(string.Format(CultureInfo.CurrentCulture, SR.Cryptography_Xml_SelfReferenceRequiresContext, _uri)); } // Normalize the containing document resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); XmlDocument docWithNoComments = Utils.DiscardComments(Utils.PreProcessDocumentInput(document, resolver, baseUri)); hashInputStream = TransformChain.TransformToOctetStream(docWithNoComments, resolver, baseUri); } else if (_uri[0] == '#') { // If we get here, then we are constructing a Reference to an embedded DataObject // referenced by an Id = attribute. Go find the relevant object bool discardComments = true; string idref = Utils.GetIdFromLocalUri(_uri, out discardComments); if (idref == "xpointer(/)") { // This is a self referencial case if (document == null) { throw new CryptographicException(string.Format(CultureInfo.CurrentCulture, SR.Cryptography_Xml_SelfReferenceRequiresContext, _uri)); } // We should not discard comments here!!! resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream(Utils.PreProcessDocumentInput(document, resolver, baseUri), resolver, baseUri); break; } XmlElement elem = SignedXml.GetIdElement(document, idref); if (elem != null) { _namespaces = Utils.GetPropagatedAttributes(elem.ParentNode as XmlElement); } if (elem == null) { // Go throw the referenced items passed in if (refList != null) { foreach (XmlNode node in refList) { XmlElement tempElem = node as XmlElement; if ((tempElem != null) && (Utils.HasAttribute(tempElem, "Id", SignedXml.XmlDsigNamespaceUrl)) && (Utils.GetAttribute(tempElem, "Id", SignedXml.XmlDsigNamespaceUrl).Equals(idref))) { elem = tempElem; if (_signedXml._context != null) { _namespaces = Utils.GetPropagatedAttributes(_signedXml._context); } break; } } } } if (elem == null) { throw new CryptographicException(SR.Cryptography_Xml_InvalidReference); } XmlDocument normDocument = Utils.PreProcessElementInput(elem, resolver, baseUri); // Add the propagated attributes Utils.AddNamespaces(normDocument.DocumentElement, _namespaces); resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); if (discardComments) { // We should discard comments before going into the transform chain XmlDocument docWithNoComments = Utils.DiscardComments(normDocument); hashInputStream = TransformChain.TransformToOctetStream(docWithNoComments, resolver, baseUri); } else { // This is an XPointer reference, do not discard comments!!! hashInputStream = TransformChain.TransformToOctetStream(normDocument, resolver, baseUri); } } else { throw new CryptographicException(SR.Cryptography_Xml_UriNotResolved, _uri); } break; case ReferenceTargetType.XmlElement: // We need to create a DocumentNavigator out of the XmlElement resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream(Utils.PreProcessElementInput((XmlElement)_refTarget, resolver, baseUri), resolver, baseUri); break; default: throw new CryptographicException(SR.Cryptography_Xml_UriNotResolved, _uri); } // Compute the new hash value hashInputStream = SignedXmlDebugLog.LogReferenceData(this, hashInputStream); hashval = _hashAlgorithm.ComputeHash(hashInputStream); } finally { if (hashInputStream != null) { hashInputStream.Close(); } if (response != null) { response.Close(); } if (inputStream != null) { inputStream.Close(); } } return(hashval); }
/// <summary> /// Log that an X509 chain is being built for a certificate /// </summary> /// <param name="signedXml">SignedXml object building the chain</param> /// <param name="chain">chain built for the certificate</param> /// <param name="certificate">certificate having the chain built for it</param> internal static void LogVerifyX509Chain(SignedXml signedXml, X509Chain chain, X509Certificate certificate) { Debug.Assert(signedXml != null, "signedXml != null"); Debug.Assert(certificate != null, "certificate != null"); Debug.Assert(chain != null, "chain != null"); if (InformationLoggingEnabled) { string buildMessage = SR.Format(CultureInfo.InvariantCulture, SR.Log_BuildX509Chain, GetKeyName(certificate)); WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.X509Verification, buildMessage); } if (VerboseLoggingEnabled) { // Dump out the flags and other miscelanious information used for building string revocationMode = SR.Format(CultureInfo.InvariantCulture, SR.Log_RevocationMode, chain.ChainPolicy.RevocationFlag); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, revocationMode); string revocationFlag = SR.Format(CultureInfo.InvariantCulture, SR.Log_RevocationFlag, chain.ChainPolicy.RevocationFlag); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, revocationFlag); string verificationFlags = SR.Format(CultureInfo.InvariantCulture, SR.Log_VerificationFlag, chain.ChainPolicy.VerificationFlags); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, verificationFlags); string verificationTime = SR.Format(CultureInfo.InvariantCulture, SR.Log_VerificationTime, chain.ChainPolicy.VerificationTime); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, verificationTime); string urlTimeout = SR.Format(CultureInfo.InvariantCulture, SR.Log_UrlTimeout, chain.ChainPolicy.UrlRetrievalTimeout); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, urlTimeout); } // If there were any errors in the chain, make sure to dump those out if (InformationLoggingEnabled) { foreach (X509ChainStatus status in chain.ChainStatus) { if (status.Status != X509ChainStatusFlags.NoError) { string logMessage = SR.Format(CultureInfo.InvariantCulture, SR.Log_X509ChainError, status.Status, status.StatusInformation); WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.X509Verification, logMessage); } } } // Finally, dump out the chain itself if (VerboseLoggingEnabled) { StringBuilder chainElements = new StringBuilder(); chainElements.Append(SR.Log_CertificateChain); foreach (X509ChainElement element in chain.ChainElements) { chainElements.AppendFormat(CultureInfo.InvariantCulture, " {0}", GetKeyName(element.Certificate)); } WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, chainElements.ToString()); } }