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));
		}
Exemplo n.º 2
0
        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;
		}