private static void Serialize(SoapSignature soapSignature, XmlDocument document, XmlNode root)
        {
            if (soapSignature == null)
            {
                throw new ArgumentNullException(nameof(soapSignature));
            }

            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            if (root == null)
            {
                throw new ArgumentNullException(nameof(root));
            }

            var signatureNode              = document.CreateElement(Constants.XmlPrefixes.Ds, Constants.XmlRootNames.Signature, Constants.XmlNamespaces.Ds);
            var signedInfoNode             = document.CreateElement(Constants.XmlPrefixes.Ds, Constants.XmlRootNames.SignedInfo, Constants.XmlNamespaces.Ds);
            var canonicalizationMethodNode = document.CreateElement(Constants.XmlPrefixes.Ds, Constants.XmlRootNames.CanonicalizationMethod, Constants.XmlNamespaces.Ds);
            var signatureMethodNode        = document.CreateElement(Constants.XmlPrefixes.Ds, Constants.XmlRootNames.SignatureMethod, Constants.XmlNamespaces.Ds);
            var signatureValueNode         = document.CreateElement(Constants.XmlPrefixes.Ds, Constants.XmlRootNames.SignatureValue, Constants.XmlNamespaces.Ds);

            signatureNode.SetAttribute($"Id", soapSignature.Id);
            canonicalizationMethodNode.SetAttribute(Constants.XmlAttributeNames.Algorithm, soapSignature.CanonicalizationMethod);
            signatureMethodNode.SetAttribute(Constants.XmlAttributeNames.Algorithm, soapSignature.SignatureMethod);
            signatureValueNode.InnerText = soapSignature.SignatureValue;

            signedInfoNode.AppendChild(canonicalizationMethodNode);
            signedInfoNode.AppendChild(signatureMethodNode);
            if (soapSignature.References != null)
            {
                foreach (var reference in soapSignature.References)
                {
                    Serialize(reference, document, signedInfoNode);
                }
            }

            signatureNode.AppendChild(signedInfoNode);
            signatureNode.AppendChild(signatureValueNode);
            Serialize(soapSignature.KeyInfo, document, signatureNode);
            root.AppendChild(signatureNode);
        }
Esempio n. 2
0
        public SoapSignature BuildSignatureWithEid(SoapEnvelope soapEnvelope, string pin, IBeIdCardConnector connector)
        {
            if (soapEnvelope == null)
            {
                throw new ArgumentNullException(nameof(soapEnvelope));
            }

            if (string.IsNullOrWhiteSpace(pin))
            {
                throw new ArgumentNullException(nameof(pin));
            }

            if (connector == null)
            {
                throw new ArgumentNullException(nameof(connector));
            }

            var    serializer  = new SoapMessageSerializer(); // Serialize into XML.
            var    xmlDocument = serializer.Serialize(soapEnvelope);
            string xml         = null;

            using (var strWriter = new StringWriter())
            {
                using (var xmlTextWriter = XmlWriter.Create(strWriter))
                {
                    xmlDocument.WriteTo(xmlTextWriter);
                    xmlTextWriter.Flush();
                    xml = strWriter.GetStringBuilder().ToString();
                }
            }

            var nsmgr = new XmlNamespaceManager(xmlDocument.NameTable); // 1. Construct the SignedInfo.

            nsmgr.AddNamespace(Common.Saml.Constants.XmlPrefixes.Wsu, Common.Saml.Constants.XmlNamespaces.Wsu);
            nsmgr.AddNamespace(Common.Saml.Constants.XmlPrefixes.SoapEnv, Common.Saml.Constants.XmlNamespaces.SoapEnvelope);
            nsmgr.AddNamespace(Common.Saml.Constants.XmlPrefixes.Wsse, Common.Saml.Constants.XmlNamespaces.Wsse);
            nsmgr.AddNamespace(Common.Saml.Constants.XmlPrefixes.Ds, Common.Saml.Constants.XmlNamespaces.Ds);
            var bodyTokenNode   = xmlDocument.SelectSingleNode($"//{Common.Saml.Constants.XmlPrefixes.SoapEnv}:Body", nsmgr);
            var timeStampNode   = xmlDocument.SelectSingleNode($"//{Common.Saml.Constants.XmlPrefixes.Wsu}:Timestamp", nsmgr);
            var binaryTokenNode = xmlDocument.SelectSingleNode($"//{Common.Saml.Constants.XmlPrefixes.Wsse}:BinarySecurityToken", nsmgr);
            var timeStampId     = timeStampNode.Attributes[$"{Common.Saml.Constants.XmlPrefixes.Wsu}:Id"].Value;
            var binaryTokenId   = binaryTokenNode.Attributes[$"{Common.Saml.Constants.XmlPrefixes.Wsu}:Id"].Value;
            var bodyTokenId     = bodyTokenNode.Attributes[$"{Common.Saml.Constants.XmlPrefixes.Wsu}:Id"].Value;
            var signatureNode   = Canonilize(xml, new[]
            {
                timeStampId,
                binaryTokenId,
                bodyTokenId
            });

            var c14Serializer = new XmlDsigExcC14NTransform();  // 2. Compute the signature value.
            var c14Doc        = new XmlDocument();

            c14Doc.LoadXml(signatureNode.FirstChild.OuterXml);
            c14Serializer.LoadInput(c14Doc);
            var c14n = new StreamReader((Stream)c14Serializer.GetOutput(typeof(Stream))).ReadToEnd();
            var signedInfoPayload = Encoding.UTF8.GetBytes(c14n);
            var b64 = Convert.ToBase64String(signedInfoPayload);

            byte[] hashResult = null;
            using (var sha = new SHA1CryptoServiceProvider())
            {
                hashResult = sha.ComputeHash(signedInfoPayload);
            }

            var b64Hash = Convert.ToBase64String(hashResult);

            byte[] signatureValue      = null; // 3. Construct the result.
            var    certificate         = connector.GetAuthenticateCertificate();
            var    applicationName     = "medikit";
            var    digestAlgo          = BeIDDigest.Sha1;
            var    fileType            = FileType.NonRepudiationCertificate;
            var    requireSecureReader = false;

            signatureValue = connector.SignWithNoneRepudationCertificate(hashResult, digestAlgo, requireSecureReader, applicationName, pin);

            var signatureValueB64 = Convert.ToBase64String(signatureValue);
            var soapKeyInfo       = new SoapKeyInfo(GenerateId("KI"),
                                                    GenerateId("STR"),
                                                    $"#{binaryTokenId}");
            var result         = new SoapSignature(GenerateId("SIG"), signatureValueB64, soapKeyInfo);
            var referenceNodes = signatureNode.SelectNodes($"//{Common.Saml.Constants.XmlPrefixes.Ds}:Reference", nsmgr);

            foreach (XmlNode referenceNode in referenceNodes)
            {
                var uri             = referenceNode.Attributes["URI"].Value;
                var digestValueNode = referenceNode.SelectSingleNode($"{Common.Saml.Constants.XmlPrefixes.Ds}:DigestValue", nsmgr);
                result.References.Add(new SoapReference(uri, digestValueNode.InnerText));
            }

            return(result);
        }