public void ComputeSignature() { if (key != null) { if (m_signature.SignedInfo.SignatureMethod == null) { //defaults do RSA SHA256 Signature m_signature.SignedInfo.SignatureMethod = XmlDsigConstants.XmlDsigRSASHA256Url; } var sd = SignatureMethodParser.Parse(m_signature.SignedInfo.SignatureMethod); IDigest hash = XmlEncHashes.GetHashByName(sd.HashName); DigestReferences(); ISigner signer = null; // in need for a CryptoConfig factory if (key is DsaKeyParameters) { if (sd.CipherName != "DSA") { throw new CryptographicException("DSA SignatureAlgorithm is not supported by the signing key."); } signer = new DsaDigestSigner(new DsaSigner(), hash); } else if (key is RsaKeyParameters) { if (sd.CipherName != "RSA") { throw new CryptographicException("RSA SignatureAlgorithm is not supported by the signing key."); } signer = new RsaDigestSigner(hash); } if (signer != null) { signer.Init(true, key); byte[] signed = SignerHelper.ComputeSignature(signer, SignedInfoTransformed()); m_signature.SignatureValue = signed; } } else { throw new CryptographicException("signing key is not specified"); } }
private byte[] GetReferenceHash(Reference r, bool check_hmac) { Stream s = null; XmlDocument doc = null; if (r.Uri == String.Empty) { doc = envdoc; } else if (r.Type == XmlSignature.Uri.Manifest) { doc = GetManifest(r); } else { doc = new XmlDocument(); doc.PreserveWhitespace = true; string objectName = null; if (r.Uri.StartsWith("#xpointer")) { string uri = string.Join("", r.Uri.Substring(9).Split(whitespaceChars)); if (uri.Length < 2 || uri [0] != '(' || uri [uri.Length - 1] != ')') { // FIXME: how to handle invalid xpointer? uri = String.Empty; } else { uri = uri.Substring(1, uri.Length - 2); } if (uri == "/") { doc = envdoc; } else if (uri.Length > 6 && uri.StartsWith("id(") && uri [uri.Length - 1] == ')') { // id('foo'), id("foo") objectName = uri.Substring(4, uri.Length - 6); } } else if (r.Uri [0] == '#') { objectName = r.Uri.Substring(1); } else if (xmlResolver != null) { // TODO: test but doc says that Resolver = null -> no access try { // no way to know if valid without throwing an exception Uri uri = new Uri(r.Uri); s = (Stream)xmlResolver.GetEntity(uri, null, typeof(Stream)); } catch { // may still be a local file (and maybe not xml) s = File.OpenRead(r.Uri); } } if (objectName != null) { XmlElement found = null; foreach (DataObject obj in m_signature.ObjectList) { if (obj.Id == objectName) { found = obj.GetXml(this.namespaceManager); found.SetAttribute("xmlns", XmlDsigConstants.XmlDsigNamespaceUrl); doc.AppendChild(doc.ImportNode(found, true)); // FIXME: there should be theoretical justification of copying namespace declaration nodes this way. foreach (XmlNode n in found.ChildNodes) { // Do not copy default namespace as it must be xmldsig namespace for "Object" element. if (n.NodeType == XmlNodeType.Element) { FixupNamespaceNodes(n as XmlElement, doc.DocumentElement, true); } } break; } } if (found == null && envdoc != null) { found = GetIdElement(envdoc, objectName); if (found != null) { doc.AppendChild(doc.ImportNode(found, true)); FixupNamespaceNodes(found, doc.DocumentElement, false); //Copy root document namespaces to signedproperties //FixupNamespaceNodes(envdoc.DocumentElement, doc.DocumentElement, false); } } if (found == null) { throw new CryptographicException(String.Format("Malformed reference object: {0}", objectName)); } } } if (r.TransformChain.Count > 0) { foreach (Transform t in r.TransformChain) { if (s == null) { s = ApplyTransform(t, doc); } else { t.LoadInput(s); object o = t.GetOutput(); if (o is Stream) { s = (Stream)o; } else { s = CanonicalizeOutput(o); } } } } else if (s == null) { // we must not C14N references from outside the document // e.g. non-xml documents if (r.Uri [0] != '#') { s = new MemoryStream(); doc.Save(s); } else { // apply default C14N transformation s = ApplyTransform(new XmlDsigC14NTransform(), doc); } } //Used to debug the output of the canonicalizer. We are having some problems related to //different canonicalizer outputs between this implementation and Apache's santuario library. if (DebugOutput) { if (Directory.Exists(DebugOutputFolder)) { FileStream fs = new FileStream(Path.Combine(DebugOutputFolder, GetSafeFilename("ref" + r.Uri + ".xml")), FileMode.Create); CopyStream(s, fs); fs.Close(); s.Position = 0; } } return(XmlEncHashes.ComputeHash(r.DigestMethod, s)); }