示例#1
0
        private XmlDocument SignSmev2(GostFlavor gostFlavor, XmlDocument doc, X509Certificate2 certificate)
        {
            XmlNode root       = doc.SelectSingleNode("/*");
            string  rootPrefix = root?.Prefix;
            //----------------------------------------------------------------------------------------------CREATE STRUCTURE
            XmlDocument tDoc = AddTemplate(doc, certificate);
            //----------------------------------------------------------------------------------------------ROOT PREFIX
            XmlElement bodyElement  = tDoc.GetElementsByTagName(rootPrefix + ":Body")[0] as XmlElement;
            string     referenceUri = bodyElement?.GetAttribute("wsu:Id");
            //----------------------------------------------------------------------------------------------SignedXML CREATE
            //нужен для корректной отработки wsu:reference
            Smev2SignedXml signedXml = new Smev2SignedXml(tDoc)
            {
                SigningKey = certificate.PrivateKey
            };
            //----------------------------------------------------------------------------------------------REFERNCE
            Reference reference = new Reference
            {
#pragma warning disable 612
                DigestMethod = GostAlgorithmSelector.GetHashAlgorithmDescriptor(gostFlavor),
                //CPSignedXml.XmlDsigGost3411UrlObsolete,
#pragma warning restore 612
                Uri = "#" + referenceUri
            };

            XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform();

            reference.AddTransform(c14);

            signedXml.AddReference(reference);
            //----------------------------------------------------------------------------------------------SIGNATURE SETUP
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
#pragma warning disable 612
            signedXml.SignedInfo.SignatureMethod = GostAlgorithmSelector.GetSignatureAlgorithmDescriptor(gostFlavor);
            //CPSignedXml.XmlDsigGost3410UrlObsolete;
#pragma warning disable 612
            //----------------------------------------------------------------------------------------------KEYINFO
            KeyInfo         keyInfo     = new KeyInfo();
            KeyInfoX509Data x509KeyInfo = new KeyInfoX509Data(certificate);
            keyInfo.AddClause(x509KeyInfo);
            signedXml.KeyInfo = keyInfo;
            //----------------------------------------------------------------------------------------------SIGN DOCUMENT
            signedXml.ComputeSignature();
            //----------------------------------------------------------------------------------------------GET XML
            XmlElement xmlDigitalSignature = signedXml.GetXml();
            //----------------------------------------------------------------------------------------------APPEND SIGNATURE TAGS
            tDoc.GetElementsByTagName("Signature")[0].PrependChild(
                tDoc.ImportNode(xmlDigitalSignature.GetElementsByTagName("SignatureValue")[0], true));
            tDoc.GetElementsByTagName("Signature")[0].PrependChild(
                tDoc.ImportNode(xmlDigitalSignature.GetElementsByTagName("SignedInfo")[0], true));
            ((XmlElement)tDoc.GetElementsByTagName("Signature")[0]).SetAttribute("xmlns", DS_NS);

            return(tDoc);
        }
示例#2
0
        public static bool VerifySignature(SignatureType mode, XmlDocument message, X509Certificate2 cert = null, string certificateThumb = null, string nodeId = null)
        {
            SignedXml      signedXml      = new SignedXml(message);
            Smev2SignedXml smev2SignedXml = null;

            Dictionary <string, XmlElement> signatures = new Dictionary <string, XmlElement>();

            XmlNodeList signaturesInDoc =
                message.GetElementsByTagName(
                    "Signature", SignedXml.XmlDsigNamespaceUrl
                    );

            if (signaturesInDoc.Count < 1)
            {
                throw new Exception($"NO_SIGNATURES_FOUND] No signatures found in the input file.");
            }
            signatures =
                signaturesInDoc
                .Cast <XmlElement>()
                .ToDictionary((elt) => {
                XNamespace ns = elt.GetXElement().Name.Namespace;
                string sigRef = elt.GetXElement().Descendants(ns + "Reference").First().Attributes("URI").First().Value;
                return(elt.GetXElement().Descendants(ns + "Reference").First().Attributes("URI").First().Value.Replace("#", ""));
            },
                              (elt => elt)
                              );

            if (!string.IsNullOrEmpty(nodeId) && !signatures.ContainsKey(nodeId))
            {
                throw new Exception($"REFERENCED_SIGNATURE_NOT_FOUND] Referenced signature (-node_id=<{nodeId}>) not found in the input file.");
            }

            switch (mode)
            {
            case SignatureType.Smev2BaseDetached:
                smev2SignedXml = new Smev2SignedXml(message);
                try {
                    smev2SignedXml.LoadXml(!string.IsNullOrEmpty(nodeId) ? signatures[nodeId] : signatures["body"]);
                } catch (Exception e) {
                    throw new Exception($"CERTIFICATE_CONTENT_CORRUPTED] <X509Certificate> node content appears to be corrupted. Message: {e.Message}");
                }
                XmlNodeList referenceList = smev2SignedXml.KeyInfo
                                            .GetXml()
                                            .GetElementsByTagName("Reference", WSSecurityWSSENamespaceUrl);
                if (referenceList.Count == 0)
                {
                    throw new Exception("SMEV2_CERTIFICATE_REFERENCE_NOT_FOUND] No certificate reference found in input file");
                }
                string binaryTokenReference = ((XmlElement)referenceList[0]).GetAttribute("URI");
                if (string.IsNullOrEmpty(binaryTokenReference) || binaryTokenReference[0] != '#')
                {
                    throw new Exception("SMEV2_MALFORMED_CERTIFICATE_REFERENCE] Certificate reference appears to be malformed");
                }

                XmlElement binaryTokenElement = smev2SignedXml.GetIdElement(message, binaryTokenReference.Substring(1));
                if (binaryTokenElement == null)
                {
                    throw new Exception($"SMEV2_CERTIFICATE_NOT_FOUND] Referenced certificate not found. Reference: <{binaryTokenReference.Substring(1)}>");
                }

                try {
                    cert = new X509Certificate2(Convert.FromBase64String(binaryTokenElement.InnerText));
                } catch (Exception e) {
                    throw new Exception($"SMEV2_CERTIFICATE_CORRUPTED] Smev2 certificate node content appears to be corrupted. Message: {e.Message}");
                }
                break;

            case SignatureType.Smev2ChargeEnveloped:
                if (signaturesInDoc.Count > 1)
                {
                    throw new Exception($"CHARGE_TOO_MANY_SIGNATURES_FOUND] More than one signature found. Found: {signaturesInDoc.Count} sigantures.");
                }
                if (!_chargeStructureOk(message))
                {
                    throw new Exception($"CHARGE_MALFORMED_DOCUMENT] Document structure is malformed. <Signature> node must be either root node descendant or root node descentant descendant.");
                }

                try {
                    signedXml.LoadXml(signatures.First().Value);
                } catch (Exception e) {
                    throw new Exception($"CERTIFICATE_CONTENT_CORRUPTED] <X509Certificate> node content appears to be corrupted. Message: {e.Message}");
                }

                break;

            case SignatureType.Smev2SidebysideDetached:
            case SignatureType.Smev3BaseDetached:
            case SignatureType.Smev3SidebysideDetached:
                try {
                    signedXml.LoadXml(!string.IsNullOrEmpty(nodeId) ? signatures[nodeId] : signatures.First().Value);
                } catch (Exception e) {
                    throw new Exception($"CERTIFICATE_CONTENT_CORRUPTED] <X509Certificate> node content appears to be corrupted. Message: {e.Message}");
                }
                break;

            case SignatureType.SigDetached:
            case SignatureType.Smev3Ack:
                throw new Exception($"UNSUPPORTED_SIGNATURE_TYPE] Signature type <{mode}> is unsupported. Possible values are : <smev2_base.enveloped>, <smev2_charge.enveloped>, <smev2_sidebyside.detached>, <smev3_base.detached>");
            }

            bool result = smev2SignedXml == null ?
                          cert == null?signedXml.CheckSignature() : signedXml.CheckSignature(cert, true) :
                              smev2SignedXml.CheckSignature(cert.PublicKey.Key);

            return(result);
        }