void CollectSupportingTokensCore ( SupportingTokenInfoCollection l, SupportingTokenParameters s, bool required) { foreach (SecurityTokenParameters p in s.Signed) l.Add (new SupportingTokenInfo (GetSigningToken (p), SecurityTokenAttachmentMode.Signed, required)); foreach (SecurityTokenParameters p in s.Endorsing) l.Add (new SupportingTokenInfo (GetSigningToken (p), SecurityTokenAttachmentMode.Endorsing, required)); foreach (SecurityTokenParameters p in s.SignedEndorsing) l.Add (new SupportingTokenInfo (GetSigningToken (p), SecurityTokenAttachmentMode.SignedEndorsing, required)); foreach (SecurityTokenParameters p in s.SignedEncrypted) l.Add (new SupportingTokenInfo (GetSigningToken (p), SecurityTokenAttachmentMode.SignedEncrypted, required)); }
Signature CreateSignature (XmlDocument doc, XmlElement body, XmlNamespaceManager nsmgr, SupportingTokenInfoCollection tokenInfos, SecurityKeyIdentifierClause actualClause, SymmetricAlgorithm actualKey, SecurityToken signToken, bool includeSigToken, bool signatureProtection, WSSecurityMessageHeader header, Collection<WSSignedXml> endorsedSignatures, ref string bodyId) { // sign // see clause 8 of WS-SecurityPolicy C.2.2 WSSignedXml sxml = new WSSignedXml (doc); SecurityTokenReferenceKeyInfo sigKeyInfo; XmlElement secElem = null; var sigSpec = SignaturePart; var serializer = security.TokenSerializer; var suite = security.Element.DefaultAlgorithmSuite; var sig = sxml.Signature; sig.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm; foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/u:Timestamp", nsmgr)) CreateReference(sig, elem, elem.GetAttribute ("Id", Constants.WsuNamespace)); foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) CreateReference(sig, elem, elem.GetAttribute ("Id", Constants.WsuNamespace)); foreach (SupportingTokenInfo tinfo in tokenInfos) if (tinfo.Mode != SecurityTokenAttachmentMode.Endorsing) { XmlElement el = sxml.GetIdElement (doc, tinfo.Token.Id); CreateReference (sig, el, el.GetAttribute ("Id", Constants.WsuNamespace)); } XmlNodeList nodes = doc.SelectNodes ("/s:Envelope/s:Header/*", nsmgr); for (int i = 0; i < msg.Headers.Count; i++) { MessageHeaderInfo h = msg.Headers [i]; if (h.Name == "Security" && h.Namespace == Constants.WssNamespace) secElem = nodes [i] as XmlElement; else if ((sigSpec.HeaderTypes.Count == 0 || sigSpec.HeaderTypes.Contains (new XmlQualifiedName(h.Name, h.Namespace))) && (msg.Version.Addressing != AddressingVersion.None || !String.Equals (h.Name, "Action", StringComparison.Ordinal))) { string id = GenerateId (doc); h.Id = id; CreateReference (sig, nodes [i] as XmlElement, id); } } if (sigSpec.IsBodyIncluded) { bodyId = GenerateId (doc); CreateReference (sig, body.ParentNode as XmlElement, bodyId); } if (security.DefaultSignatureAlgorithm == SignedXml.XmlDsigHMACSHA1Url) { // FIXME: use appropriate hash algorithm sxml.ComputeSignature (new HMACSHA1(actualKey.Key)); sigKeyInfo = new SecurityTokenReferenceKeyInfo (actualClause, serializer, doc); } else { SecurityKeyIdentifierClause signClause = CounterParameters.CallCreateKeyIdentifierClause (signToken, includeSigToken ? CounterParameters.ReferenceStyle : SecurityTokenReferenceStyle.External); AsymmetricSecurityKey signKey = (AsymmetricSecurityKey)signToken.ResolveKeyIdentifierClause (signClause); sxml.SigningKey = signKey.GetAsymmetricAlgorithm (security.DefaultSignatureAlgorithm, true); sxml.ComputeSignature (); sigKeyInfo = new SecurityTokenReferenceKeyInfo (signClause, serializer, doc); } sxml.KeyInfo = new KeyInfo (); sxml.KeyInfo.AddClause (sigKeyInfo); if (!signatureProtection) header.AddContent (sig); // endorse the signature with (signed)endorsing // supporting tokens. foreach (SupportingTokenInfo tinfo in tokenInfos) { switch (tinfo.Mode) { case SecurityTokenAttachmentMode.Endorsing: case SecurityTokenAttachmentMode.SignedEndorsing: if (sxml.Signature.Id == null) { sig.Id = GenerateId (doc); secElem.AppendChild (sxml.GetXml ()); } WSSignedXml ssxml = new WSSignedXml (doc); ssxml.Signature.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm; CreateReference (ssxml.Signature, doc, sig.Id); SecurityToken sst = tinfo.Token; SecurityKey ssk = sst.SecurityKeys [0]; // FIXME: could be different? SecurityKeyIdentifierClause tclause = new LocalIdKeyIdentifierClause (sst.Id); // FIXME: could be different? if (ssk is SymmetricSecurityKey) { SymmetricSecurityKey signKey = (SymmetricSecurityKey)ssk; ssxml.ComputeSignature (signKey.GetKeyedHashAlgorithm(suite.DefaultSymmetricSignatureAlgorithm)); } else { AsymmetricSecurityKey signKey = (AsymmetricSecurityKey)ssk; ssxml.SigningKey = signKey.GetAsymmetricAlgorithm (suite.DefaultAsymmetricSignatureAlgorithm, true); ssxml.ComputeSignature (); } ssxml.KeyInfo.AddClause (new SecurityTokenReferenceKeyInfo (tclause, serializer, doc)); if (!signatureProtection) header.AddContent (ssxml.Signature); endorsedSignatures.Add (ssxml); break; } } return sig; }
public SupportingTokenInfoCollection CollectSupportingTokens (string action) { SupportingTokenInfoCollection tokens = new SupportingTokenInfoCollection (); SupportingTokenParameters supp; CollectSupportingTokensCore (tokens, Element.EndpointSupportingTokenParameters, true); if (Element.OperationSupportingTokenParameters.TryGetValue (action, out supp)) CollectSupportingTokensCore (tokens, supp, true); CollectSupportingTokensCore (tokens, Element.OptionalEndpointSupportingTokenParameters, false); if (Element.OptionalOperationSupportingTokenParameters.TryGetValue (action, out supp)) CollectSupportingTokensCore (tokens, supp, false); return tokens; }