Author: atsushi
Date: 2007-02-06 17:14:54 -0500 (Tue, 06 Feb 2007)
New Revision: 72381

Modified:
   trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog
   
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/MessageSecurityBindingSupport.cs
   
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageDecryptor.cs
   
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageGenerator.cs
   
trunk/olive/class/System.ServiceModel/Test/System.ServiceModel.Security/ChangeLog
   
trunk/olive/class/System.ServiceModel/Test/System.ServiceModel.Security/WSSecurityTokenSerializerTest.cs
Log:
2007-02-06  Atsushi Enomoto  <[EMAIL PROTECTED]>

        * MessageSecurityBindingSupport.cs : added CreateTokenAuthenticator()
          for supporting 'supporting tokens' .
        * SecureMessageGenerator.cs : Supporting token creation is done only
          at initiator (not sure if it is supposed that, but for now it is).
          Removed extraneous CollectSupportingTokens().
        * SecureMessageDecryptor.cs : implemented supporting token
          authentication (partly). "Signed" supporting tokens are expected
          to work fine.

        * WSSecurityTokenSerializerTest.cs: some tests for writing derived-
          key-involved key identifier clauses.



Modified: 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog
===================================================================
--- 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog    
    2007-02-06 22:09:28 UTC (rev 72380)
+++ 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog    
    2007-02-06 22:14:54 UTC (rev 72381)
@@ -1,5 +1,16 @@
 2007-02-06  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
+       * MessageSecurityBindingSupport.cs : added CreateTokenAuthenticator()
+         for supporting 'supporting tokens' .
+       * SecureMessageGenerator.cs : Supporting token creation is done only
+         at initiator (not sure if it is supposed that, but for now it is).
+         Removed extraneous CollectSupportingTokens().
+       * SecureMessageDecryptor.cs : implemented supporting token
+         authentication (partly). "Signed" supporting tokens are expected
+         to work fine.
+
+2007-02-06  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
        * SecureMessageGenerator.cs :
          make SignBeforeEncryptAndEncryptSignature working.
 

Modified: 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/MessageSecurityBindingSupport.cs
===================================================================
--- 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/MessageSecurityBindingSupport.cs
 2007-02-06 22:09:28 UTC (rev 72380)
+++ 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/MessageSecurityBindingSupport.cs
 2007-02-06 22:14:54 UTC (rev 72381)
@@ -174,6 +174,13 @@
                        return manager.CreateSecurityTokenProvider 
(requirement);
                }
 
+               public SecurityTokenAuthenticator CreateTokenAuthenticator 
(SecurityTokenParameters p, out SecurityTokenResolver resolver)
+               {
+                       SecurityTokenRequirement r = CreateRequirement ();
+                       p.CallInitializeSecurityTokenRequirement (r);
+                       return manager.CreateSecurityTokenAuthenticator (r, out 
resolver);
+               }
+
                public void CreateTokenAuthenticator (SecurityTokenRequirement 
requirement)
                {
                        authenticator = 
manager.CreateSecurityTokenAuthenticator (requirement, out auth_token_resolver);

Modified: 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageDecryptor.cs
===================================================================
--- 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageDecryptor.cs
        2007-02-06 22:09:28 UTC (rev 72380)
+++ 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageDecryptor.cs
        2007-02-06 22:14:54 UTC (rev 72381)
@@ -60,6 +60,10 @@
                        this.security = security;
                }
 
+               public override MessageDirection Direction {
+                       get { return MessageDirection.Input; }
+               }
+
                public override byte [] ActiveKey {
                        get { return null; }
                }
@@ -90,6 +94,10 @@
                        get { return active_key; }
                }
 
+               public override MessageDirection Direction {
+                       get { return MessageDirection.Output; }
+               }
+
                public override SecurityTokenParameters Parameters {
                        get { return security.InitiatorParameters; }
                }
@@ -136,6 +144,7 @@
 
                }
 
+               public abstract MessageDirection Direction { get; }
                public abstract SecurityTokenParameters Parameters { get; }
                public abstract SecurityTokenParameters CounterParameters { 
get; }
                public abstract byte [] ActiveKey { get; }
@@ -160,7 +169,7 @@
 
                        XmlNodeList securityHeaders = doc.SelectNodes 
("/s:Envelope/s:Header/o:Security", nsmgr);
                        foreach (XmlElement secElem in securityHeaders)
-                               // FIXME: check Actor.
+                               // FIXME: check Actor. There is only one 
o:Security which we should handle.
                                ExtractSecurity (secElem);
 
                        Message msg = Message.CreateMessage (new XmlNodeReader 
(doc), srcmsg.Headers.Count, srcmsg.Version);
@@ -283,7 +292,6 @@
                                ed2.LoadXml (el);
                                byte [] key = GetEncryptionKeyForData (ed2, 
encXml, map);
                                aes.Key = key != null ? key : decryptedKey;
-                               if (ed2.GetXml () == null) throw new Exception 
("Gyabo");
                                encXml.ReplaceData (el, DecryptLax (encXml, 
ed2, aes));
                        }
 
@@ -297,8 +305,6 @@
                        if (sigElem == null)
                                throw new MessageSecurityException ("The the 
message signature is expected but not found.");
 
-                       // FIXME: the security tokens must be authenticated.
-
                        WSSignedXml sxml = new WSSignedXml (nsmgr, doc);
                        sxml.LoadXml (sigElem);
                        SecurityTokenSerializer serializer =
@@ -318,25 +324,126 @@
                        if (security.DefaultSignatureAlgorithm == 
SignedXml.XmlDsigHMACSHA1Url)
                                confirmed = sxml.CheckSignature (new HMACSHA1 
(aes.Key));
                        else {
+                               // my guess is that this could also apply to 
symmetric binding case i.e. key resolution could be done as 
WrappedKeySecurityToken resolution.
                                SecurityKey signKey;
                                SecurityTokenResolver outband = 
security.OutOfBandTokenResolver;
                                SecurityToken signToken;
                                if (!in_band_resolver.TryResolveToken 
(sigClause, out signToken) &&
                                    (outband == null || 
!outband.TryResolveToken (sigClause, out signToken)))
                                        throw new MessageSecurityException 
(String.Format ("The signing key could not be resolved from {0}", signKey));
+                               signKey = signToken.ResolveKeyIdentifierClause 
(sigClause);
+                               AsymmetricAlgorithm sigalg = 
((AsymmetricSecurityKey) signKey).GetAsymmetricAlgorithm 
(security.DefaultSignatureAlgorithm, false);
+                               confirmed = sxml.CheckSignature (sigalg);
+
+                               // FIXME: it should not apply only to 
asymmetric case.
                                sec_prop.InitiatorToken = new 
SecurityTokenSpecification (
                                        signToken,
                                        
security.TokenAuthenticator.ValidateToken (signToken));
-                               signKey = signToken.ResolveKeyIdentifierClause 
(sigClause);
-                               AsymmetricAlgorithm sigalg = 
((AsymmetricSecurityKey) signKey).GetAsymmetricAlgorithm 
(security.DefaultSignatureAlgorithm, false);
-                               confirmed = sxml.CheckSignature (sigalg);
                        }
                        if (!confirmed)
                                throw new MessageSecurityException ("Message 
signature is invalid.");
+
+                       // token authentication
+                       // FIXME: it might not be limited to recipient
+                       if (Direction == MessageDirection.Input)
+                               ProcessSupportingTokens (sxml);
+
                        sec_prop.EncryptionKey = decryptedKey;
                        sec_prop.ConfirmedSignatures.Add 
(Convert.ToBase64String (sxml.SignatureValue));
                }
 
+               #region supporting token processing
+
+               // authenticate and map supporting tokens to proper 
SupportingTokenSpecification list.
+               void ProcessSupportingTokens (SignedXml sxml)
+               {
+                       List<SupportingTokenInfo> tokens = new 
List<SupportingTokenInfo> ();
+               
+                       // First, categorize those tokens in the Security
+                       // header:
+                       // - Endorsing          signing
+                       // - Signed                     signed
+                       // - SignedEncrypted            signed  encrypted
+                       // - SignedEndorsing    signing signed
+
+                       foreach (object obj in wss_header.Contents) {
+                               SecurityToken token = obj as SecurityToken;
+                               if (token == null)
+                                       continue;
+                               bool signed = false, endorsing = false, 
encrypted = false;
+                               // signed
+                               foreach (Reference r in 
sxml.SignedInfo.References)
+                                       if (r.Uri.Substring (1) == token.Id) {
+                                               signed = true;
+                                               break;
+                                       }
+                               // FIXME: how to get 'encrypted' state?
+                               // FIXME: endorsing
+
+                               SecurityTokenAttachmentMode mode =
+                                       signed ? encrypted ? 
SecurityTokenAttachmentMode.SignedEncrypted :
+                                       endorsing ? 
SecurityTokenAttachmentMode.SignedEndorsing :
+                                       SecurityTokenAttachmentMode.Signed :
+                                       SecurityTokenAttachmentMode.Endorsing;
+                               tokens.Add (new SupportingTokenInfo (token, 
mode, false));
+                       }
+
+                       // then,
+                       // 1. validate every mandatory supporting token
+                       // parameters (Endpoint-, Operation-). To do that,
+                       // iterate all tokens in the header against every
+                       // parameter in the mandatory list.
+                       // 2. validate every token that is not validated.
+                       // To do that, iterate all supporting token parameters
+                       // and check if any of them can validate it.
+                       SupportingTokenParameters supp;
+                       string action = GetAction ();
+                       ValidateTokensByParameters 
(security.Element.EndpointSupportingTokenParameters, tokens, false);
+                       if 
(security.Element.OperationSupportingTokenParameters.TryGetValue (action, out 
supp))
+                               ValidateTokensByParameters (supp, tokens, 
false);
+                       ValidateTokensByParameters 
(security.Element.OptionalEndpointSupportingTokenParameters, tokens, true);
+                       if 
(security.Element.OptionalOperationSupportingTokenParameters.TryGetValue 
(action, out supp))
+                               ValidateTokensByParameters (supp, tokens, true);
+               }
+
+               void ValidateTokensByParameters (SupportingTokenParameters 
supp, List<SupportingTokenInfo> tokens, bool optional)
+               {
+                       ValidateTokensByParameters (supp.Endorsing, tokens, 
optional);
+                       ValidateTokensByParameters (supp.Signed, tokens, 
optional);
+                       ValidateTokensByParameters (supp.SignedEndorsing, 
tokens, optional);
+                       ValidateTokensByParameters (supp.SignedEncrypted, 
tokens, optional);
+               }
+
+               void ValidateTokensByParameters 
(IEnumerable<SecurityTokenParameters> plist, List<SupportingTokenInfo> tokens, 
bool optional)
+               {
+                       foreach (SecurityTokenParameters p in plist) {
+                               SecurityTokenResolver r;
+                               SecurityTokenAuthenticator a =
+                                       security.CreateTokenAuthenticator (p, 
out r);
+                               SupportingTokenSpecification spec = 
ValidateTokensByParameters (a, r, tokens);
+                               if (spec == null) {
+                                       if (optional)
+                                               continue;
+                                       else
+                                               throw new 
MessageSecurityException ("Security token '{0}' cannot be validated according 
to the security settings.");
+                               }
+                               sec_prop.IncomingSupportingTokens.Add (spec);
+                       }
+               }
+
+               SupportingTokenSpecification ValidateTokensByParameters 
(SecurityTokenAuthenticator a, SecurityTokenResolver r, 
List<SupportingTokenInfo> tokens)
+               {
+                       foreach (SupportingTokenInfo info in tokens)
+                               if (a.CanValidateToken (info.Token))
+                                       return new SupportingTokenSpecification 
(
+                                               info.Token,
+                                               a.ValidateToken (info.Token),
+                                               info.Mode);
+                       return null;
+               }
+
+               #endregion
+
                byte [] GetEncryptionKeyForData (EncryptedData ed2, 
EncryptedXml encXml, Dictionary<string,byte[]> map)
                {
                        SecurityTokenSerializer serializer =

Modified: 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageGenerator.cs
===================================================================
--- 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageGenerator.cs
        2007-02-06 22:09:28 UTC (rev 72380)
+++ 
trunk/olive/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageGenerator.cs
        2007-02-06 22:14:54 UTC (rev 72381)
@@ -110,11 +110,6 @@
                public override ScopedMessagePartSpecification EncryptionParts 
{ 
                        get { return 
Security.ChannelRequirements.IncomingEncryptionParts; }
                }
-
-               public override SupportingTokenInfoCollection 
CollectSupportingTokens ()
-               {
-                       return security.CollectSupportingTokens (GetAction ());
-               }
        }
 
        internal class RecipientMessageSecurityGenerator : 
MessageSecurityGenerator
@@ -176,11 +171,6 @@
                public override ScopedMessagePartSpecification EncryptionParts 
{ 
                        get { return 
Security.ChannelRequirements.OutgoingEncryptionParts; }
                }
-
-               public override SupportingTokenInfoCollection 
CollectSupportingTokens ()
-               {
-                       return security.CollectSupportingTokens (GetAction ());
-               }
        }
 
        internal abstract class MessageSecurityGenerator
@@ -235,8 +225,6 @@
                        }
                }
 
-               public abstract SupportingTokenInfoCollection 
CollectSupportingTokens ();
-
                public abstract bool ShouldIncludeToken 
(SecurityTokenInclusionMode mode, bool isInitialized);
 
                public bool ShouldOutputEncryptedKey {
@@ -300,6 +288,14 @@
                                foreach (string value in 
secprop.ConfirmedSignatures)
                                        header.Contents.Add (new 
Wss11SignatureConfirmation (GenerateId (doc), value));
 
+                       SupportingTokenInfoCollection tokenInfos =
+                               Direction == MessageDirection.Input ?
+                               security.CollectSupportingTokens (GetAction ()) 
:
+                               new SupportingTokenInfoCollection (); // empty
+                       foreach (SupportingTokenInfo tokenInfo in tokenInfos)
+                               if (tokenInfo.Mode != 
SecurityTokenAttachmentMode.Endorsing)
+                                       header.Contents.Add (tokenInfo.Token);
+
                        // populate DOM to sign.
                        XPathNavigator nav = doc.CreateNavigator ();
                        using (XmlWriter w = nav.AppendChild ()) {
@@ -317,8 +313,6 @@
                        EncryptedData sigenc = null;
 
 
-                       SupportingTokenInfoCollection tokens = 
CollectSupportingTokens ();
-
                        List<WsscDerivedKeyToken> derivedKeys =
                                new List<WsscDerivedKeyToken> ();
 

Modified: 
trunk/olive/class/System.ServiceModel/Test/System.ServiceModel.Security/ChangeLog
===================================================================
--- 
trunk/olive/class/System.ServiceModel/Test/System.ServiceModel.Security/ChangeLog
   2007-02-06 22:09:28 UTC (rev 72380)
+++ 
trunk/olive/class/System.ServiceModel/Test/System.ServiceModel.Security/ChangeLog
   2007-02-06 22:14:54 UTC (rev 72381)
@@ -1,6 +1,11 @@
 2007-02-06  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
        * WSSecurityTokenSerializerTest.cs : added test for reading
+         empty (invalid) UsernameToken.
+
+2007-02-06  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
+       * WSSecurityTokenSerializerTest.cs : added test for reading
          EncryptedKeySHA1 embedded key.
 
 2007-02-05  Atsushi Enomoto  <[EMAIL PROTECTED]>

Modified: 
trunk/olive/class/System.ServiceModel/Test/System.ServiceModel.Security/WSSecurityTokenSerializerTest.cs
===================================================================
--- 
trunk/olive/class/System.ServiceModel/Test/System.ServiceModel.Security/WSSecurityTokenSerializerTest.cs
    2007-02-06 22:09:28 UTC (rev 72380)
+++ 
trunk/olive/class/System.ServiceModel/Test/System.ServiceModel.Security/WSSecurityTokenSerializerTest.cs
    2007-02-06 22:14:54 UTC (rev 72381)
@@ -46,6 +46,9 @@
        [TestFixture]
        public class WSSecurityTokenSerializerTest
        {
+               const string wssNS = 
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";;
+               const string wsuNS = 
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";;
+
                static X509Certificate2 cert = new X509Certificate2 
("Test/Resources/test.pfx", "mono");
 
                const string derived_key_token1 = @"<c:DerivedKeyToken 
xmlns:c='http://schemas.xmlsoap.org/ws/2005/02/sc'>
@@ -553,6 +556,17 @@
                }
 
                [Test]
+               [ExpectedException (typeof (XmlException))] // not sure how 
this exception type makes sense...
+               public void ReadEmptyUsernameToken ()
+               {
+                       WSSecurityTokenSerializer serializer =
+                               WSSecurityTokenSerializer.DefaultInstance;
+                       using (XmlReader xr = XmlReader.Create (new 
StringReader (String.Format ("<o:UsernameToken u:Id='urn:foo' xmlns:o='{0}' 
xmlns:u='{1}' />", wssNS, wsuNS)))) {
+                               SecurityToken token = serializer.ReadToken (xr, 
null);
+                       }
+               }
+
+               [Test]
                [ExpectedException (typeof (XmlException))] // tokenResolver is 
null
                [Category ("NotWorking")]
                public void ReadTokenDerivedKeyTokenNullResolver ()

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to