Beispiel #1
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));
        }
Beispiel #2
0
        public VerifierResponse VerifyXmlSignature(
            SignatureType mode,
            XmlDocument message,
            string certificateFilePath = null,
            string certificateThumb    = null,
            string nodeId = null,
            bool isVerifyCertificateChain = false)
        {
            SignedXml signedXml = new SignedXml(message);

            Signer.Smev2SignedXml smev2SignedXml = null;

            X509Certificate2 cert = null;
            bool             isCerFile;

            if ((isCerFile = !string.IsNullOrEmpty(certificateFilePath)) ||
                !string.IsNullOrEmpty(certificateThumb))
            {
                //means we are testing signature on external certificate
                if (isCerFile)
                {
                    cert = new X509Certificate2();
                    try
                    {
                        cert.Import(certificateFilePath);
                    }
                    catch (Exception e)
                    {
                        throw ExceptionFactory.GetException(
                                  ExceptionType.CertificateImportException,
                                  certificateFilePath,
                                  e.Message);
                    }
                }
                else
                {
                    //throws if not found
                    ICertificateProcessor cp = new CertificateProcessor();
                    cert = cp.SearchCertificateByThumbprint(certificateThumb);
                }
            }

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

            var signatures =
                signaturesInDoc
                .Cast <XmlElement>()
                .ToDictionary(
                    (elt) =>
            {
                XNamespace ns = elt.GetXElement().Name.Namespace;
                return(elt.GetXElement().Descendants(ns + "Reference").First().Attributes("URI").First()
                       .Value.Replace("#", ""));
            },
                    (elt => elt)
                    );

            if (!string.IsNullOrEmpty(nodeId) &&
                !signatures.ContainsKey(nodeId))
            {
                throw ExceptionFactory.GetException(ExceptionType.ReferencedSignatureNotFound, nodeId);
            }

            if (signaturesInDoc.Count == 0)
            {
                throw ExceptionFactory.GetException(ExceptionType.NoSignaturesFound);
            }

            switch (mode)
            {
            case SignatureType.Smev2BaseDetached:
                smev2SignedXml = new Signer.Smev2SignedXml(message);
                try
                {
                    smev2SignedXml.LoadXml(
                        !string.IsNullOrEmpty(nodeId)
                                                                ? signatures[nodeId]
                                                                : signatures["body"]);
                }
                catch (Exception e)
                {
                    throw ExceptionFactory.GetException(ExceptionType.CertificateContentCorrupted, e.Message);
                }

                XmlNodeList referenceList =
                    smev2SignedXml.KeyInfo
                    .GetXml()
                    .GetElementsByTagName("Reference", Signer.WsSecurityWsseNamespaceUrl);
                if (referenceList.Count == 0)
                {
                    throw ExceptionFactory.GetException(ExceptionType.Smev2CertificateReferenceNotFound);
                }

                string binaryTokenReference = ((XmlElement)referenceList[0]).GetAttribute("URI");
                if (string.IsNullOrEmpty(binaryTokenReference) ||
                    binaryTokenReference[0] != '#')
                {
                    throw ExceptionFactory.GetException(ExceptionType.Smev2MalformedCertificateReference);
                }

                XmlElement binaryTokenElement = smev2SignedXml.GetIdElement(
                    message,
                    binaryTokenReference.Substring(1));
                if (binaryTokenElement == null)
                {
                    throw ExceptionFactory.GetException(
                              ExceptionType.Smev2CertificateNotFound,
                              binaryTokenReference.Substring(1));
                }

                try
                {
                    cert = new X509Certificate2(Convert.FromBase64String(binaryTokenElement.InnerText));
                }
                catch (Exception e)
                {
                    throw ExceptionFactory.GetException(ExceptionType.Smev2CertificateCorrupted, e.Message);
                }

                break;

            case SignatureType.Smev2ChargeEnveloped:
                if (signaturesInDoc.Count > 1)
                {
                    throw ExceptionFactory.GetException(
                              ExceptionType.ChargeTooManySignaturesFound,
                              signaturesInDoc.Count);
                }

                if (!ChargeStructureOk(message))
                {
                    throw ExceptionFactory.GetException(ExceptionType.ChargeMalformedDocument);
                }

                try
                {
                    signedXml.LoadXml(signatures.First().Value);
                }
                catch (Exception e)
                {
                    throw ExceptionFactory.GetException(ExceptionType.CertificateContentCorrupted, e.Message);
                }

                break;

            case SignatureType.Smev2SidebysideDetached:
            case SignatureType.Smev3BaseDetached:
            case SignatureType.Smev3SidebysideDetached:
                try
                {
                    XmlDsigSmevTransform smevTransform = new XmlDsigSmevTransform();
                    signedXml.SafeCanonicalizationMethods.Add(smevTransform.Algorithm);

                    signedXml.LoadXml(
                        !string.IsNullOrEmpty(nodeId)
                                                                ? signatures[nodeId]
                                                                : signatures.First().Value);
                }
                catch (Exception e)
                {
                    throw ExceptionFactory.GetException(ExceptionType.CertificateContentCorrupted, e.Message);
                }

                break;

            case SignatureType.Pkcs7String:
            case SignatureType.Pkcs7StringAllCert:
            case SignatureType.Pkcs7StringNoCert:
            case SignatureType.SigDetached:
            case SignatureType.SigDetachedAllCert:
            case SignatureType.SigDetachedNoCert:
                throw new NotSupportedException(
                          $"Detached signature verification is not supported by this method. Use {nameof(VerifyDetachedSignature)} method instead.");

            case SignatureType.Unknown:
            case SignatureType.Smev3Ack:
            case SignatureType.Rsa2048Sha256String:
            case SignatureType.RsaSha256String:
                throw ExceptionFactory.GetException(ExceptionType.UnsupportedSignatureType, mode);

            default:
                throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
            }

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

            var isCertificateChainValid = cert?.Verify() ?? true;

            StringBuilder verificationMessage = new StringBuilder();

            if (!isSignatureValid)
            {
                verificationMessage.AppendLine("Signature is invalid");
            }

            if (!isCertificateChainValid)
            {
                verificationMessage.AppendLine("Certificate chain is invalid");
            }

            var verifierResponse = new VerifierResponse()
            {
                IsCertificateChainValid        = isCertificateChainValid,
                IsSignatureMathematicallyValid = isSignatureValid,
                IsSignatureSigningDateValid    = true,              // we do not check this for this type of signature
                Message = verificationMessage.ToString()
            };

            return(verifierResponse);
        }