Esempio n. 1
0
        //Should get data from XmlDocument, not file
        private static bool VerifySignedXmlLastSignWithoutCertificateVerification(XmlDocument xmlDocument)
        {
            try {
                // Create a new SignedXml object and pass it
                SignedXml signedXml = new SignedXml(xmlDocument);

                // Find the "Signature" node and create a new
                // XmlNodeList object.
                XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");

                // Load the signature node.
                signedXml.LoadXml((XmlElement)nodeList[nodeList.Count - 1]);

                //////////////////////////////////Extract key - Start
                X509Certificate2 x509 = GetLastSignerCertificate(xmlDocument);
                //////////////////////////////////Extract key - End

                AsymmetricAlgorithm key;
                bool signatureCheckStatus = signedXml.CheckSignatureReturningKey(out key);
                if (signatureCheckStatus)
                {
                    XmlElement metaElement = (XmlElement)nodeList[nodeList.Count - 1].LastChild;
                    return(VerifyMetaDataObjectSignature(metaElement, key));
                }
                else
                {
                    return(false);
                }
                //return signedXml.CheckSignature(key);
                //return signedXml.CheckSignature(certificate, true);
            } catch (Exception exception) {
                Console.Write("Error: " + exception);
                throw exception;
            }
        }
        public ActionResult Index(XmlModel model)
        {
            if (model.Action == "encrypt")
            {
                var recipientCertificate = LoadCertificate(model.RecipientThumbprint);
                var signingCertificate   = LoadCertificate(model.SenderThumbprint);
                var xmlDocument          = new XmlDocument();
                xmlDocument.LoadXml(model.PlainText);

                var elementToEncrypt = xmlDocument.GetElementsByTagName("message")[0] as XmlElement;
                var encryptedXml     = new EncryptedXml();

                // Encrypt the element.
                var encryptedElement = encryptedXml.Encrypt(elementToEncrypt, recipientCertificate);
                EncryptedXml.ReplaceElement(elementToEncrypt, encryptedElement, false);

                // Sign the document
                var signedXml = new SignedXml(xmlDocument)
                {
                    SigningKey = signingCertificate.PrivateKey
                };
                var reference = new Reference {
                    Uri = string.Empty
                };

                var transform = new XmlDsigC14NTransform();
                reference.AddTransform(transform);

                var envelope = new XmlDsigEnvelopedSignatureTransform();
                reference.AddTransform(envelope);
                signedXml.AddReference(reference);

                var keyInfo = new KeyInfo();
                keyInfo.AddClause(new KeyInfoX509Data(signingCertificate));
                signedXml.KeyInfo = keyInfo;
                signedXml.ComputeSignature();

                var xmlDigitalSignature = signedXml.GetXml();
                xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(xmlDigitalSignature, true));

                model.PlainText = "";
                model.Envelope  = XmlToString(xmlDocument);
            }
            else if (model.Action == "decrypt")
            {
                var xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(model.Envelope);

                // Validate the signature
                var signedXml = new SignedXml(xmlDocument);
                var nodeList  = xmlDocument.GetElementsByTagName("Signature");

                if (nodeList.Count <= 0)
                {
                    throw new Exception("No signature found.");
                }

                signedXml.LoadXml((XmlElement)nodeList[0]);

                // XML signatures allows signing only parts of a document or
                // even worse, can refer to another resource that's not even
                // part of the document containing the signature. To make
                // sure that the signature we're validating is actually signing
                // the document we have to check the reference. An empty
                // reference refers to the entire enclosing document.
                if (signedXml.SignedInfo.References.Cast <Reference>().Single().Uri != "")
                {
                    throw new Exception("Signature does not refer to entire document. Validating signatures for part of the document is not supported by this code.");
                }

                AsymmetricAlgorithm signingKey;
                if (!signedXml.CheckSignatureReturningKey(out signingKey))
                {
                    throw new Exception("Invalid Signature");
                }
                else
                {
                    IEnumerable <X509Certificate2> keyInfoCertificates =
                        signedXml.KeyInfo.OfType <KeyInfoX509Data>()
                        .SelectMany(x => x.Certificates.Cast <X509Certificate2>());
                    var signingCertificate = keyInfoCertificates.FirstOrDefault(x => x.PublicKey.Key == signingKey);
                    if (signingCertificate == null)
                    {
                        throw new Exception("Signing certificate not found in KeyInfo.");
                    }
                    model.SenderSubject = signingCertificate.Subject;
                }

                var encryptedXml = new EncryptedXml(xmlDocument);
                encryptedXml.DecryptDocument();

                model.Envelope  = "";
                model.PlainText = XmlToString(xmlDocument);
            }

            ModelState.Clear();
            model.RecipientThumbprint = RecipientThumbprint;
            model.SenderThumbprint    = SenderThumbprint;
            return(View(model));
        }