private static XmlDocument GetDocumentFromDetachedOrEnvelopingSignature(XmlDocument signedXml)
        {
            var signedInfoNode          = XmlHelper.DescendantWith(signedXml.DocumentElement, XmlDsigNodesHelper.IsSignedInfoNode);
            var referenceToContentsNode = XmlHelper.DescendantWith(signedInfoNode, XmlDsigNodesHelper.IsReferenceToOriginalContent);

            if (referenceToContentsNode == null)
            {
                throw new Exception("Reference to Original Content not found");
            }
            var uri = XmlHelper.AttributeOf(referenceToContentsNode, "URI");

            if (uri.StartsWith("#"))
            {
                uri = uri.Substring(1);
            }
            if (XmlDsigNodesHelper.ReferenceIsDetached(referenceToContentsNode))
            {
                return(XmlHelper.ReadXmlFromUri(uri));
            }
            var results      = new XmlDocument();
            var contentsNode = XmlHelper.DescendantWith(signedXml.DocumentElement, n => XmlDsigNodesHelper.ObjectNodeWithIdAsUri(n, uri));

            results.LoadXml(contentsNode.InnerXml);
            return(results);
        }
        private static XmlDocument GetDocumentFromSignature(XmlDocument signedXml)
        {
            var rootNode = signedXml.DocumentElement;

            if (XmlDsigNodesHelper.IsSignatureNode(rootNode))
            {
                return(GetDocumentFromDetachedOrEnvelopingSignature(signedXml));
            }
            return(GetDocumentFromEnvelopedSignature(signedXml));
        }
        private static string GetTimeStampFromSignature(XmlDocument document)
        {
            var rootNode      = document.DocumentElement;
            var signatureNode = XmlDsigNodesHelper.IsSignatureNode(rootNode) ?
                                rootNode : XmlHelper.DescendantWith(rootNode, XmlDsigNodesHelper.IsSignatureNode);

            if (signatureNode == null)
            {
                throw new Exception("Signature node not found");
            }
            var timestamps = XmlHelper.FindNodesIn(signatureNode, "Object/SignatureProperties/SignatureProperty/Timestamp");

            return(timestamps.Count == 0 ? "" : timestamps[0].InnerText);
        }
        private static X509Certificate2 GetCertificateFromSignature(XmlDocument signedXml)
        {
            var signatureNode = signedXml.DocumentElement;

            if (!XmlDsigNodesHelper.IsSignatureNode(signatureNode))
            {
                signatureNode = XmlHelper.DescendantWith(signatureNode, XmlDsigNodesHelper.IsSignatureNode);
            }
            var keyInfoNode     = XmlHelper.DescendantWith(signatureNode, XmlDsigNodesHelper.IsKeyInfo);
            var x509Data        = XmlHelper.DescendantWith(keyInfoNode, XmlDsigNodesHelper.IsX509Data);
            var x509Certificate = XmlHelper.DescendantWith(x509Data, XmlDsigNodesHelper.IsX509Certificate);

            return(new X509Certificate2(Convert.FromBase64String(x509Certificate.InnerText)));
        }
        private static VerificationResults PerformValidationFromXml(string xml, VerificationParameters validationParameters)
        {
            var document = new XmlDocument {
                PreserveWhitespace = true
            };

            document.LoadXml(xml);

            var newsignedXml = new ExtendedSignedXml(document);

            if (document.DocumentElement == null)
            {
                throw new InvalidDocumentException("Document has no root element");
            }

            var signatureNode = XmlDsigNodesHelper.GetSignatureNode(document);

            newsignedXml.LoadXml(signatureNode);

            var verificationCertificate = GetVerificationCertificate(newsignedXml, validationParameters);

            if (verificationCertificate == null)
            {
                throw new Exception("Signer public key could not be found");
            }
            if (!newsignedXml.CheckSignature(verificationCertificate, !validationParameters.VerifyCertificate))
            {
                throw new InvalidOperationException("Signature is invalid.");
            }
            var results = new VerificationResults
            {
                Timestamp          = GetTimeStampFromSignature(document),
                OriginalDocument   = GetDocumentFromSignature(document),
                SigningCertificate = GetCertificateFromSignature(document)
            };

            return(results);
        }