Ejemplo n.º 1
0
        public string Sign(
            SignatureType mode,
            GostFlavor gostFlavor,
            string certificateThumbprint,
            string signThisPath,
            bool assignDs,
            string nodeToSign,
            bool ignoreExpiredCert = false,
            bool?isAddSigningTime  = null)
        {
            XmlDocument xmlToSign    = null;
            string      stringToSign = null;

            byte[] bytesToSign = null;

            if (
                assignDs &&
                !new List <SignatureType>()
            {
                SignatureType.Smev3BaseDetached,
                SignatureType.Smev3SidebysideDetached,
                SignatureType.Smev3Ack
            }.Contains(mode))
            {
                throw ExceptionFactory.GetException(ExceptionType.DsAssignmentNotSupported);
            }

            if (mode == SignatureType.Pkcs7String ||
                mode == SignatureType.Pkcs7StringAllCert ||
                mode == SignatureType.Pkcs7StringNoCert

                || mode == SignatureType.Rsa2048Sha256String ||
                mode == SignatureType.RsaSha256String)
            {
                stringToSign = File.ReadAllText(signThisPath, Encoding.UTF8);
            }
            else if (mode == SignatureType.SigDetached ||
                     mode == SignatureType.SigDetachedAllCert ||
                     mode == SignatureType.SigDetachedNoCert)
            {
                bytesToSign = File.ReadAllBytes(signThisPath);
            }
            else
            {
                xmlToSign = new XmlDocument();
                xmlToSign.Load(signThisPath);
            }

            return(Sign(
                       mode,
                       gostFlavor,
                       certificateThumbprint,
                       xmlToSign,
                       assignDs,
                       nodeToSign,
                       ignoreExpiredCert,
                       stringToSign,
                       bytesToSign,
                       isAddSigningTime));
        }
Ejemplo n.º 2
0
        private string Sign(
            SignatureType mode,
            GostFlavor gostFlavor,
            string certificateThumbprint,
            XmlDocument signThis,
            bool assignDs,
            string nodeToSign,
            bool ignoreExpiredCert = false,
            string stringToSign    = null,
            byte[] bytesToSign     = null,
            bool?isAddSigningTime  = null)
        {
            ICertificateProcessor cp          = new CertificateProcessor();
            X509Certificate2      certificate = cp.SearchCertificateByThumbprint(certificateThumbprint);

            if (!certificate.HasPrivateKey)
            {
                throw ExceptionFactory.GetException(ExceptionType.PrivateKeyMissing, certificate.Subject);
            }

            if (!ignoreExpiredCert &&
                cp.IsCertificateExpired(certificate))
            {
                throw ExceptionFactory.GetException(ExceptionType.CertExpired, certificate.Thumbprint);
            }

            return(Sign(mode, gostFlavor, certificate, signThis, assignDs, nodeToSign, stringToSign, bytesToSign, isAddSigningTime));
        }
Ejemplo n.º 3
0
        public SignerResponse Sign(
            SignatureType mode,
            GostFlavor gostFlavor,
            string certificateThumbprint,
            byte[] bytesToSign,
            string nodeToSign,
            bool ignoreExpiredCert = false,
            bool?isAddSigningTime  = null)
        {
            XmlDocument xmlToSign           = null;
            string      stringToSign        = null;
            bool        isResultBase64Bytes = false;

            if (mode == SignatureType.Pkcs7String ||
                mode == SignatureType.Pkcs7StringAllCert ||
                mode == SignatureType.Pkcs7StringNoCert

                || mode == SignatureType.Rsa2048Sha256String ||
                mode == SignatureType.RsaSha256String)
            {
                // read binary content as string
                stringToSign        = Encoding.UTF8.GetString(bytesToSign);
                isResultBase64Bytes = true;
            }
            else if (mode == SignatureType.SigDetached ||
                     mode == SignatureType.SigDetachedAllCert ||
                     mode == SignatureType.SigDetachedNoCert)
            {
                // TODO: this is a quick and dirty fix
                // here we already have content in bytesToSign - just do nothing
                isResultBase64Bytes = true;
            }
            else
            {
                xmlToSign = new XmlDocument();
                var stringContent = Encoding.UTF8.GetString(bytesToSign);
                xmlToSign.LoadXml(stringContent);
            }

            //TODO: this is a very convoluted way to pass arguments. Wrap all possible input data into a class!!!

            var signedData = Sign(
                mode,
                gostFlavor,
                certificateThumbprint,
                xmlToSign,
                false,
                nodeToSign,
                ignoreExpiredCert,
                stringToSign,
                string.IsNullOrEmpty(stringToSign)
                                        ? bytesToSign
                                        : null,
                isAddSigningTime);

            return(new SignerResponse(signedData, isResultBase64Bytes));
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
 public string Sign(
     SignatureType mode,
     GostFlavor gostFlavor,
     XmlDocument signThis,
     string certificateThumbprint,
     string nodeToSign,
     bool assignDs          = false,
     bool ignoreExpiredCert = false,
     bool?isAddSigningTime  = null)
 {
     return(Sign(mode, gostFlavor, certificateThumbprint, signThis, assignDs, nodeToSign, ignoreExpiredCert, isAddSigningTime: isAddSigningTime));
 }
Ejemplo n.º 6
0
        private XmlDocument SignEnveloped(
            GostFlavor gostFlavor,
            XmlDocument doc,
            X509Certificate2 certificate,
            string nodeId = null)
        {
            //----------------------------------------------------------------------------------------------CREATE SIGNED XML
            SignedXml signedXml = new SignedXml(doc)
            {
                SigningKey = certificate.PrivateKey
            };
            //----------------------------------------------------------------------------------------------REFERNCE
            Reference reference = new Reference
            {
                Uri = nodeId,
#pragma warning disable 612
                DigestMethod = GostAlgorithmSelector.GetHashAlgorithmDescriptor(gostFlavor)
                               //CPSignedXml.XmlDsigGost3411UrlObsolete - old
#pragma warning disable 612
            };

            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

            reference.AddTransform(env);
            XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform();

            reference.AddTransform(c14);

            // Add the reference to the SignedXml object.
            signedXml.AddReference(reference);
            //----------------------------------------------------------------------------------------------SIGNATURE SETUP
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            signedXml.SignedInfo.SignatureMethod        = GostAlgorithmSelector.GetSignatureAlgorithmDescriptor(gostFlavor);
            //CPSignedXml.XmlDsigGost3410UrlObsolete; - old
            //----------------------------------------------------------------------------------------------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
            XmlNode root = doc.SelectSingleNode("/*");

            root?.AppendChild(doc.ImportNode(xmlDigitalSignature, true));

            return(doc);
        }
Ejemplo n.º 7
0
        private XmlDocument SignXmlNode(
            GostFlavor gostFlavor,
            XmlDocument doc,
            X509Certificate2 certificate,
            string nodeId)
        {
            //----------------------------------------------------------------------------------------------CREATE SIGNED XML
            SignedXml signedXml = new SignedXml(doc)
            {
                SigningKey = certificate.PrivateKey
            };
            //----------------------------------------------------------------------------------------------REFERNCE
            Reference reference = new Reference
            {
                Uri = "#" + nodeId,
#pragma warning disable 612
                DigestMethod = GostAlgorithmSelector.GetHashAlgorithmDescriptor(gostFlavor)
                               //CPSignedXml.XmlDsigGost3411UrlObsolete - old
#pragma warning disable 612
            };

            XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform();

            reference.AddTransform(c14);

            // Add the reference to the SignedXml object.
            signedXml.AddReference(reference);
            //----------------------------------------------------------------------------------------------SIGNATURE SETUP
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            signedXml.SignedInfo.SignatureMethod        = GostAlgorithmSelector.GetSignatureAlgorithmDescriptor(gostFlavor);
            //CPSignedXml.XmlDsigGost3410UrlObsolete;
            //----------------------------------------------------------------------------------------------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 TO DOCUMENT

            GetNodeWithAttributeValue(doc.ChildNodes, nodeId)?.ParentNode?.AppendChild(xmlDigitalSignature);

            return(doc);
        }
Ejemplo n.º 8
0
        public static string GetHashAlgorithmDescriptor(GostFlavor gostFlavor)
        {
            switch (gostFlavor)
            {
            case GostFlavor.Gost_Obsolete:
#pragma warning disable 612
                return(CPSignedXml.XmlDsigGost3411UrlObsolete);

#pragma warning restore 612
            case GostFlavor.Gost2012_256:
                return(CPSignedXml.XmlDsigGost3411_2012_256Url);

            case GostFlavor.Gost2012_512:
                return(CPSignedXml.XmlDsigGost3411_2012_512Url);

            default:
                throw new ArgumentOutOfRangeException(nameof(gostFlavor), gostFlavor, null);
            }
        }
Ejemplo n.º 9
0
        private string Sign(
            SignatureType mode,
            GostFlavor gostFlavor,
            X509Certificate2 cert,
            XmlDocument signThis,
            bool assignDs,
            string nodeToSign,
            string stringToSign   = null,
            byte[] bytesToSign    = null,
            bool?isAddSigningTime = null)
        {
            XmlDocument signedXmlDoc = new XmlDocument();

            try
            {
                switch (mode)
                {
                case SignatureType.Smev2SidebysideDetached:
                    if (string.IsNullOrEmpty(nodeToSign))
                    {
                        throw ExceptionFactory.GetException(ExceptionType.NodeIdRequired);
                    }

                    signedXmlDoc = SignXmlNode(gostFlavor, signThis, cert, nodeToSign);
                    break;

                case SignatureType.Smev2ChargeEnveloped:
                    signedXmlDoc = SignEnveloped(gostFlavor, signThis, cert);
                    break;

                case SignatureType.Smev2BaseDetached:
                    signedXmlDoc = SignSmev2(gostFlavor, signThis, cert);
                    break;

                case SignatureType.Smev3BaseDetached:
                    if (string.IsNullOrEmpty(nodeToSign))
                    {
                        throw ExceptionFactory.GetException(ExceptionType.NodeIdRequired);
                    }

                    signedXmlDoc = SignSmev3(gostFlavor, signThis, cert, nodeToSign, assignDs);
                    break;

                case SignatureType.Smev3SidebysideDetached:
                    if (string.IsNullOrEmpty(nodeToSign))
                    {
                        throw ExceptionFactory.GetException(ExceptionType.NodeIdRequired);
                    }

                    signedXmlDoc = SignSmev3(
                        gostFlavor,
                        signThis,
                        cert,
                        nodeToSign,
                        assignDs,
                        isAck: false,
                        isSidebyside: true);
                    break;

                case SignatureType.Smev3Ack:
                    if (string.IsNullOrEmpty(nodeToSign))
                    {
                        throw ExceptionFactory.GetException(ExceptionType.NodeIdRequired);
                    }

                    signedXmlDoc = SignSmev3(gostFlavor, signThis, cert, nodeToSign, assignDs, isAck: true);
                    break;

                case SignatureType.SigDetached:
                    return(Convert.ToBase64String(SignPkcs7(bytesToSign, cert, X509IncludeOption.EndCertOnly, isAddSigningTime ?? false)));

                case SignatureType.SigDetachedNoCert:
                    return(Convert.ToBase64String(SignPkcs7(bytesToSign, cert, X509IncludeOption.None, isAddSigningTime ?? false)));

                case SignatureType.SigDetachedAllCert:
                    return(Convert.ToBase64String(SignPkcs7(bytesToSign, cert, X509IncludeOption.WholeChain, isAddSigningTime ?? false)));

                case SignatureType.Pkcs7String:
                    return(Convert.ToBase64String(
                               SignStringPkcs7(stringToSign, cert, X509IncludeOption.EndCertOnly, isAddSigningTime ?? false)));

                case SignatureType.Pkcs7StringNoCert:
                    return(Convert.ToBase64String(SignStringPkcs7(stringToSign, cert, X509IncludeOption.None, isAddSigningTime ?? false)));

                case SignatureType.Pkcs7StringAllCert:
                    return(Convert.ToBase64String(
                               SignStringPkcs7(stringToSign, cert, X509IncludeOption.WholeChain, isAddSigningTime ?? false)));

                case SignatureType.Rsa2048Sha256String:
                    return(Convert.ToBase64String(SignStringRsa2048Sha256(stringToSign, cert)));

                case SignatureType.RsaSha256String:
                    return(Convert.ToBase64String(SignStringRsaSha(stringToSign, cert, ShaAlgorithmType.Sha256)));
                }
            }
            catch (Exception e)
            {
                throw ExceptionFactory.GetException(ExceptionType.UnknownSigningException, e.Message);
            }

            return(signedXmlDoc.InnerXml);
        }
Ejemplo n.º 10
0
        private XmlDocument SignSmev3(
            GostFlavor gostFlavor,
            XmlDocument doc,
            X509Certificate2 certificate,
            string signingNodeId,
            bool assignDs,
            bool isAck        = false,
            bool isSidebyside = false)
        {
            XmlNamespaceManager nsm = new XmlNamespaceManager(doc.NameTable);

            nsm.AddNamespace("ns", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1");
            nsm.AddNamespace("ns1", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1");
            nsm.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");

            SignedXml sxml = new SignedXml(doc)
            {
                SigningKey = certificate.PrivateKey
            };

            XmlDsigSmevTransform smevTransform = new XmlDsigSmevTransform();

            sxml.SafeCanonicalizationMethods.Add(smevTransform.Algorithm);

            //=====================================================================================REFERENCE TRASFORMS
            Reference reference = new Reference
            {
                Uri = "#" + signingNodeId,
#pragma warning disable 612
                //Расчет хеш-суммы ГОСТ Р 34.11-94 / 34.11.2012 http://www.w3.org/2001/04/xmldsig-more#gostr3411
                DigestMethod = GostAlgorithmSelector.GetHashAlgorithmDescriptor(gostFlavor)
                               //CPSignedXml.XmlDsigGost3411UrlObsolete - old one
#pragma warning disable 612
            };

            XmlDsigExcC14NTransform excC14N = new XmlDsigExcC14NTransform();

            reference.AddTransform(excC14N);
            reference.AddTransform(smevTransform);

            if (isAck)
            {
                XmlDsigEnvelopedSignatureTransform enveloped
                    = new XmlDsigEnvelopedSignatureTransform();
                reference.AddTransform(enveloped);
            }

            sxml.AddReference(reference);

            //=========================================================================================CREATE SIGNATURE
            sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

            //Формирование подписи ГОСТ Р 34.10-2001 / 34.10-2012 http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411
            sxml.SignedInfo.SignatureMethod = GostAlgorithmSelector.GetSignatureAlgorithmDescriptor(gostFlavor);
            //CPSignedXml.XmlDsigGost3410UrlObsolete; - old one
            KeyInfo         keyInfo     = new KeyInfo();
            KeyInfoX509Data x509KeyInfo = new KeyInfoX509Data(certificate);

            keyInfo.AddClause(x509KeyInfo);
            sxml.KeyInfo = keyInfo;

            sxml.ComputeSignature();

            XmlElement signature = sxml.GetXml();

            //==================================================================================================add ds:
            if (assignDs)
            {
                AssignNsPrefix(signature, "ds");
                XmlElement xmlSignedInfo = signature.SelectSingleNode("ds:SignedInfo", nsm) as XmlElement;

                XmlDocument document = new XmlDocument();
                document.PreserveWhitespace = false;
                document.LoadXml(xmlSignedInfo.OuterXml);

                //create new canonicalization object based on original one
                Transform canonicalizationMethodObject
                    = sxml.SignedInfo.CanonicalizationMethodObject;
                canonicalizationMethodObject.LoadInput(document);

                //get new hshing object based on original one
                SignatureDescription description =
                    CryptoConfig.CreateFromName(sxml.SignedInfo.SignatureMethod) as SignatureDescription;
                if (description == null)
                {
                    throw new CryptographicException(
                              $"Не удалось создать объект SignatureDescription по имени [{sxml.SignedInfo.SignatureMethod}]");
                }

                HashAlgorithm hash = description.CreateDigest();
                if (hash == null)
                {
                    throw new CryptographicException(
                              $"Не удалось создать объект HashAlgorithm из SignatureDescription по имени [{sxml.SignedInfo.SignatureMethod}]");
                }

                //compute new SignedInfo digest value
                byte[] hashVal = canonicalizationMethodObject.GetDigestedOutput(hash);

                //compute new signature
                XmlElement xmlSignatureValue = signature.SelectSingleNode("ds:SignatureValue", nsm) as XmlElement;
                xmlSignatureValue.InnerText =
                    Convert.ToBase64String(description.CreateFormatter(sxml.SigningKey).CreateSignature(hashVal));
            }

            //=============================================================================APPEND SIGNATURE TO DOCUMENT
            if (!isSidebyside)
            {
                //TODO: is using SMEV types 1.2 edit this code!
                doc.GetElementsByTagName(
                    "CallerInformationSystemSignature",
                    "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1")[0].InnerXml = "";
                doc.GetElementsByTagName(
                    "CallerInformationSystemSignature",
                    "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1")[0].AppendChild(signature);
            }
            else
            {
                GetNodeWithAttributeValue(doc.ChildNodes, signingNodeId)?.ParentNode?.AppendChild(signature);
            }

            return(doc);
        }