public void Valider() { var signed = new SignedXmlWithAgnosticId(ResponseDocument); signed.LoadXml(HeaderSignatureElement); // Sørger for at motatt envelope inneholder signature confirmation og body samt at id'ne matcher mot header signatur ValiderSignaturReferences(HeaderSignatureElement, signed, new string[] { "/env:Envelope/env:Header/wsse:Security/wsse11:SignatureConfirmation", "/env:Envelope/env:Body" }); // Validerer SignatureConfirmation PerformSignatureConfirmation(HeaderSecurityElement); SjekkTimestamp(TimeSpan.FromSeconds(2000)); // Sjekker signatur if (!signed.CheckSignature(instillinger.Valideringssertifikat.PublicKey.Key)) throw new Exception("Signaturen i motatt svar er ikke gyldig"); }
protected override void AddSignatureToHeader(XmlNode node) { SignedXml signed = new SignedXmlWithAgnosticId(Document, Instillinger.Avsendersertifikat); signed.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#"; // Timestamp var tsReference = new Reference("#" + Settings.TimestampId); tsReference.AddTransform(new XmlDsigExcC14NTransform("wsse soapenv")); signed.AddReference(tsReference); // Body var bodyReference = new Reference("#" + Settings.BodyId); bodyReference.AddTransform(new XmlDsigExcC14NTransform("")); signed.AddReference(bodyReference); signed.KeyInfo.AddClause(new SecurityTokenReferenceClause(Instillinger.Avsendersertifikat)); signed.KeyInfo.Id = String.Format("KS-{0}", Guid.NewGuid()); signed.ComputeSignature(); Security.AppendChild(Document.ImportNode(signed.GetXml(), true)); }
/// <summary> /// Sjekker at soap envelopen inneholder timestamp, body og messaging element med korrekt id og referanser i security signaturen. /// </summary> protected void ValiderSignaturReferences(XmlElement signature, SignedXmlWithAgnosticId signedXml, string[] requiredReferences) { foreach (var elementXPath in requiredReferences) { // Sørg for at svar inneholde påkrevede noder. var nodes = ResponseDocument.SelectNodes(elementXPath, Nsmgr); if (nodes == null || nodes.Count == 0) { throw new Exception(string.Format("Kan ikke finne påkrevet element '{0}' i svar fra meldingsformidler.", elementXPath)); } if (nodes.Count > 1) { throw new Exception(string.Format("Påkrevet element '{0}' kan kun forekomme én gang i svar fra meldingsformidler. Ble funnet {1} ganger.", elementXPath, nodes.Count)); } // Sørg for at det finnes en refereanse til node i signatur element var elementId = nodes[0].Attributes["wsu:Id"].Value; var references = signature.SelectNodes(string.Format("./ds:SignedInfo/ds:Reference[@URI='#{0}']", elementId), Nsmgr); if (references == null || references.Count == 0) { throw new Exception(string.Format("Kan ikke finne påkrevet refereanse til element '{0}' i signatur fra meldingsformidler.", elementXPath)); } if (references.Count > 1) { throw new Exception(string.Format("Påkrevet refereanse til element '{0}' kan kun forekomme én gang i signatur fra meldingsformidler. Ble funnet {1} ganger.", elementXPath, references.Count)); } // Sørg for at Id node matcher var targetNode = signedXml.GetIdElement(ResponseDocument, elementId); if (targetNode != nodes[0]) { throw new Exception(string.Format("Signaturreferansen med id '{0}' må refererer til node med sti '{1}'", elementId, elementXPath)); } } }
/// <summary> /// Sjekker at soap envelopen inneholder timestamp, body og messaging element med korrekt id og referanser i security signaturen. /// </summary> protected void ValiderSignaturReferences(XmlElement signature, SignedXmlWithAgnosticId signedXml, string[] requiredReferences) { foreach (var elementXPath in requiredReferences) { // Sørg for at svar inneholde påkrevede noder. var nodes = ResponseDocument.SelectNodes(elementXPath, Nsmgr); if (nodes == null || nodes.Count == 0) throw new Exception(string.Format("Kan ikke finne påkrevet element '{0}' i svar fra meldingsformidler.", elementXPath)); if (nodes.Count > 1) throw new Exception(string.Format("Påkrevet element '{0}' kan kun forekomme én gang i svar fra meldingsformidler. Ble funnet {1} ganger.", elementXPath, nodes.Count)); // Sørg for at det finnes en refereanse til node i signatur element var elementId = nodes[0].Attributes["wsu:Id"].Value; var references = signature.SelectNodes(string.Format("./ds:SignedInfo/ds:Reference[@URI='#{0}']", elementId), Nsmgr); if (references == null || references.Count == 0) throw new Exception(string.Format("Kan ikke finne påkrevet refereanse til element '{0}' i signatur fra meldingsformidler.", elementXPath)); if (references.Count > 1) throw new Exception(string.Format("Påkrevet refereanse til element '{0}' kan kun forekomme én gang i signatur fra meldingsformidler. Ble funnet {1} ganger.", elementXPath, references.Count)); // Sørg for at Id node matcher var targetNode = signedXml.GetIdElement(ResponseDocument, elementId); if (targetNode != nodes[0]) throw new Exception(string.Format("Signaturreferansen med id '{0}' må refererer til node med sti '{1}'", elementId, elementXPath)); } }