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); }
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); }