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

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

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

            var keyInfoNode = document.CreateElement(Constants.XmlPrefixes.Ds, Constants.XmlRootNames.KeyInfo, Constants.XmlNamespaces.Ds);
            var securityTokenReferenceNode = document.CreateElement(Constants.XmlPrefixes.Wsse, Constants.XmlRootNames.SecurityTokenReference, Constants.XmlNamespaces.Wsse);
            var referenceNode = document.CreateElement(Constants.XmlPrefixes.Wsse, Constants.XmlRootNames.Reference, Constants.XmlNamespaces.Wsse);

            referenceNode.SetAttribute(Constants.XmlAttributeNames.Uri, keyInfo.ReferenceId);
            referenceNode.SetAttribute(Constants.XmlAttributeNames.ValueType, Constants.XmlNamespaces.ValueType);
            securityTokenReferenceNode.SetAttribute($"{Constants.XmlPrefixes.Wsse}:Id", keyInfo.SecurityTokenReferenceId);
            keyInfoNode.SetAttribute($"{Constants.XmlPrefixes.Ds}:Id", keyInfo.Id);

            securityTokenReferenceNode.AppendChild(referenceNode);
            keyInfoNode.AppendChild(securityTokenReferenceNode);

            root.AppendChild(keyInfoNode);
        }
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);
        }