Ejemplo n.º 1
0
        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");
            }
        }
Ejemplo n.º 2
0
        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));
        }