public DerivedKeySecurityToken CreateToken(SecurityToken tokenToDerive, int maxKeyLength)
 {
     DerivedKeySecurityToken result = new DerivedKeySecurityToken(this.generation, this.offset, this.length,
         this.label, this.nonce, tokenToDerive, this.tokenToDeriveIdentifier, this.derivationAlgorithm, this.Id);
     result.InitializeDerivedKey(maxKeyLength);
     return result;
 }
        public DerivedKeySecurityToken CreateToken(SecurityToken tokenToDerive, int maxKeyLength)
        {
            DerivedKeySecurityToken token = new DerivedKeySecurityToken(this.generation, this.offset, this.length, this.label, this.nonce, tokenToDerive, this.tokenToDeriveIdentifier, this.derivationAlgorithm, this.Id);

            token.InitializeDerivedKey(maxKeyLength);
            return(token);
        }
        public DerivedKeySecurityToken CreateToken(SecurityToken tokenToDerive, int maxKeyLength)
        {
            DerivedKeySecurityToken result = new DerivedKeySecurityToken(_generation, _offset, _length,
                                                                         _label, _nonce, tokenToDerive, TokenToDeriveIdentifier, _derivationAlgorithm, Id);

            result.InitializeDerivedKey(maxKeyLength);
            return(result);
        }
 private DerivedKeySecurityToken GetCachedToken(string id, int generation, int offset, int length, string label, byte[] nonce, SecurityToken tokenToDerive, SecurityKeyIdentifierClause tokenToDeriveIdentifier, string derivationAlgorithm)
 {
     for (int i = 0; i < this.cachedTokens.Length; i++)
     {
         DerivedKeySecurityTokenCache cachedToken = this.cachedTokens[i];
         if ((cachedToken != null) && this.IsMatch(cachedToken, id, generation, offset, length, label, nonce, tokenToDerive, derivationAlgorithm))
         {
             DerivedKeySecurityToken token = new DerivedKeySecurityToken(generation, offset, length, label, nonce, tokenToDerive, tokenToDeriveIdentifier, derivationAlgorithm, id);
             token.InitializeDerivedKey(cachedToken.SecurityKeys);
             return token;
         }
     }
     return null;
 }
        public void SetOutgoingSessionToken(SecurityToken token)
        {
            if (token == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
            }
            lock (ThisLock)
            {
                this.outgoingSessionToken = token;
                if (this.requireDerivedKeys)
                {
                    string derivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.Factory.MessageSecurityVersion.SecureConversationVersion);

                    this.derivedSignatureToken = new DerivedKeySecurityToken(-1, 0,
                        this.Factory.OutgoingAlgorithmSuite.GetSignatureKeyDerivationLength(token, this.Factory.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, token, this.Factory.SecurityTokenParameters.CreateKeyIdentifierClause(token, SecurityTokenReferenceStyle.Internal), derivationAlgorithm, SecurityUtils.GenerateId());
                }
            }
        }
        internal SecurityToken ResolveToken(SecurityKeyIdentifierClause keyIdentifierClause, bool matchOnlyExternal, bool resolveIntrinsicKeyClause)
        {
            if (keyIdentifierClause == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
            }

            SecurityToken resolvedToken = null;
            for (int i = 0; i < this.tokenCount; i++)
            {
                if (matchOnlyExternal && tokens[i].AllowedReferenceStyle != SecurityTokenReferenceStyle.External)
                {
                    continue;
                }

                SecurityToken token = tokens[i].Token;
                if (tokens[i].TokenParameters != null && tokens[i].TokenParameters.MatchesKeyIdentifierClause(token, keyIdentifierClause, tokens[i].AllowedReferenceStyle))
                {
                    resolvedToken = token;
                    break;
                }
                else if (tokens[i].TokenParameters == null)
                {
                    // match it according to the allowed reference style
                    if (tokens[i].AllowedReferenceStyle == SecurityTokenReferenceStyle.Internal && MatchDirectReference(token, keyIdentifierClause))
                    {
                        resolvedToken = token;
                        break;
                    }
                }
            }

            if ((resolvedToken == null) && (keyIdentifierClause is EncryptedKeyIdentifierClause))
            {
                EncryptedKeyIdentifierClause keyClause = (EncryptedKeyIdentifierClause)keyIdentifierClause;
                SecurityKeyIdentifier wrappingTokenReference = keyClause.EncryptingKeyIdentifier;
                SecurityToken unwrappingToken;
                if (this.expectedWrapper != null 
                    && CheckExternalWrapperMatch(wrappingTokenReference))
                    unwrappingToken = this.expectedWrapper;
                else
                    unwrappingToken = ResolveToken(wrappingTokenReference, true, resolveIntrinsicKeyClause);
                if (unwrappingToken != null)
                {
                    resolvedToken = SecurityUtils.CreateTokenFromEncryptedKeyClause(keyClause, unwrappingToken);
                }
            }

            if ((resolvedToken == null) && (keyIdentifierClause is X509RawDataKeyIdentifierClause) && (!matchOnlyExternal) && (resolveIntrinsicKeyClause))
            {
                resolvedToken = new X509SecurityToken(new X509Certificate2(((X509RawDataKeyIdentifierClause)keyIdentifierClause).GetX509RawData()));
            }

            byte[] derivationNonce = keyIdentifierClause.GetDerivationNonce();
            if ((resolvedToken != null) && (derivationNonce != null))
            {
                // A Implicit Derived Key is specified. Create a derived key off of the resolve token.
                if (SecurityUtils.GetSecurityKey<SymmetricSecurityKey>(resolvedToken) == null)
                {
                    // The resolved token contains no Symmetric Security key and thus we cannot create 
                    // a derived key off of it.
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.UnableToDeriveKeyFromKeyInfoClause, keyIdentifierClause, resolvedToken)));
                }

                int derivationLength = (keyIdentifierClause.DerivationLength == 0) ? DerivedKeySecurityToken.DefaultDerivedKeyLength : keyIdentifierClause.DerivationLength;
                if (derivationLength > this.securityHeader.MaxDerivedKeyLength)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.DerivedKeyLengthSpecifiedInImplicitDerivedKeyClauseTooLong, keyIdentifierClause.ToString(), derivationLength, this.securityHeader.MaxDerivedKeyLength)));
                bool alreadyDerived = false;
                for (int i = 0; i < this.tokenCount; ++i)
                {
                    DerivedKeySecurityToken derivedKeyToken = this.tokens[i].Token as DerivedKeySecurityToken;
                    if (derivedKeyToken != null)
                    {
                        if ((derivedKeyToken.Length == derivationLength) &&
                            (CryptoHelper.IsEqual(derivedKeyToken.Nonce, derivationNonce)) && 
                            (derivedKeyToken.TokenToDerive.MatchesKeyIdentifierClause(keyIdentifierClause)))
                        {
                            // This is a implcit derived key for which we have already derived the
                            // token.
                            resolvedToken = this.tokens[i].Token;
                            alreadyDerived = true;
                            break;
                        }
                    }
                }

                if (!alreadyDerived)
                {
                    string psha1Algorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.securityHeader.StandardsManager.MessageSecurityVersion.SecureConversationVersion);

                    resolvedToken = new DerivedKeySecurityToken(-1, 0, derivationLength, null, derivationNonce, resolvedToken, keyIdentifierClause, psha1Algorithm, SecurityUtils.GenerateId());
                    ((DerivedKeySecurityToken)resolvedToken).InitializeDerivedKey(derivationLength);
                    Add(resolvedToken, SecurityTokenReferenceStyle.Internal, null);
                    this.securityHeader.EnsureDerivedKeyLimitNotReached();
                }
            }

            return resolvedToken;
        }
 internal SecurityToken ResolveToken(SecurityKeyIdentifierClause keyIdentifierClause, bool matchOnlyExternal, bool resolveIntrinsicKeyClause)
 {
     if (keyIdentifierClause == null)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
     }
     SecurityToken token = null;
     for (int i = 0; i < this.tokenCount; i++)
     {
         if (!matchOnlyExternal || (this.tokens[i].AllowedReferenceStyle == SecurityTokenReferenceStyle.External))
         {
             SecurityToken token2 = this.tokens[i].Token;
             if ((this.tokens[i].TokenParameters != null) && this.tokens[i].TokenParameters.MatchesKeyIdentifierClause(token2, keyIdentifierClause, this.tokens[i].AllowedReferenceStyle))
             {
                 token = token2;
                 break;
             }
             if (((this.tokens[i].TokenParameters == null) && (this.tokens[i].AllowedReferenceStyle == SecurityTokenReferenceStyle.Internal)) && this.MatchDirectReference(token2, keyIdentifierClause))
             {
                 token = token2;
                 break;
             }
         }
     }
     if ((token == null) && (keyIdentifierClause is EncryptedKeyIdentifierClause))
     {
         SecurityToken expectedWrapper;
         EncryptedKeyIdentifierClause keyClause = (EncryptedKeyIdentifierClause) keyIdentifierClause;
         SecurityKeyIdentifier encryptingKeyIdentifier = keyClause.EncryptingKeyIdentifier;
         if ((this.expectedWrapper != null) && this.CheckExternalWrapperMatch(encryptingKeyIdentifier))
         {
             expectedWrapper = this.expectedWrapper;
         }
         else
         {
             expectedWrapper = this.ResolveToken(encryptingKeyIdentifier, true, resolveIntrinsicKeyClause);
         }
         if (expectedWrapper != null)
         {
             token = System.ServiceModel.Security.SecurityUtils.CreateTokenFromEncryptedKeyClause(keyClause, expectedWrapper);
         }
     }
     if (((token == null) && (keyIdentifierClause is X509RawDataKeyIdentifierClause)) && (!matchOnlyExternal && resolveIntrinsicKeyClause))
     {
         token = new X509SecurityToken(new X509Certificate2(((X509RawDataKeyIdentifierClause) keyIdentifierClause).GetX509RawData()));
     }
     byte[] derivationNonce = keyIdentifierClause.GetDerivationNonce();
     if ((token != null) && (derivationNonce != null))
     {
         if (System.ServiceModel.Security.SecurityUtils.GetSecurityKey<SymmetricSecurityKey>(token) == null)
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("UnableToDeriveKeyFromKeyInfoClause", new object[] { keyIdentifierClause, token })));
         }
         int length = (keyIdentifierClause.DerivationLength == 0) ? 0x20 : keyIdentifierClause.DerivationLength;
         if (length > this.securityHeader.MaxDerivedKeyLength)
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("DerivedKeyLengthSpecifiedInImplicitDerivedKeyClauseTooLong", new object[] { keyIdentifierClause.ToString(), length, this.securityHeader.MaxDerivedKeyLength })));
         }
         bool flag = false;
         for (int j = 0; j < this.tokenCount; j++)
         {
             DerivedKeySecurityToken token4 = this.tokens[j].Token as DerivedKeySecurityToken;
             if (((token4 != null) && (token4.Length == length)) && (CryptoHelper.IsEqual(token4.Nonce, derivationNonce) && token4.TokenToDerive.MatchesKeyIdentifierClause(keyIdentifierClause)))
             {
                 token = this.tokens[j].Token;
                 flag = true;
                 break;
             }
         }
         if (!flag)
         {
             string keyDerivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(this.securityHeader.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
             token = new DerivedKeySecurityToken(-1, 0, length, null, derivationNonce, token, keyIdentifierClause, keyDerivationAlgorithm, System.ServiceModel.Security.SecurityUtils.GenerateId());
             ((DerivedKeySecurityToken) token).InitializeDerivedKey(length);
             this.Add(token, SecurityTokenReferenceStyle.Internal, null);
             this.securityHeader.EnsureDerivedKeyLimitNotReached();
         }
     }
     return token;
 }
		void WriteDerivedKeySecurityToken (XmlWriter w, DerivedKeySecurityToken token)
		{
			string ns = Constants.WsscNamespace;
			w.WriteStartElement ("c", "DerivedKeyToken", ns);
			w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
			WriteKeyIdentifierClause (w, token.TokenReference);
			if (token.Name != null) {
				w.WriteStartElement ("Properties", ns);
				w.WriteElementString ("Name", ns, token.Name);
				w.WriteEndElement ();
			}
			if (token.Offset != null)
				w.WriteElementString ("Offset", ns, Convert.ToString (token.Offset));
			if (token.Length != null)
				w.WriteElementString ("Length", ns, Convert.ToString (token.Length));
			if (token.Label != null)
				w.WriteElementString ("Label", ns, token.Label);
			w.WriteElementString ("Nonce", ns, Convert.ToBase64String (token.Nonce));
			w.WriteEndElement ();
		}
 public DerivedKeySecurityTokenCache(DerivedKeySecurityToken cachedToken)
 {
     this.keyToDerive = ((SymmetricSecurityKey)cachedToken.TokenToDerive.SecurityKeys[0]).GetSymmetricKey();
     this.generation = cachedToken.Generation;
     this.offset = cachedToken.Offset;
     this.length = cachedToken.Length;
     this.label = cachedToken.Label;
     this.keyDerivationAlgorithm = cachedToken.KeyDerivationAlgorithm;
     this.nonce = cachedToken.Nonce;
     this.cachedToken = cachedToken;
 }
 private void StartSignature()
 {
     if (this.elementContainer.SourceSigningToken != null)
     {
         SecurityToken sourceSigningToken;
         SecurityKeyIdentifierClause clause2;
         SecurityTokenReferenceStyle tokenReferenceStyle = this.GetTokenReferenceStyle(this.signingTokenParameters);
         SecurityKeyIdentifierClause tokenToDeriveIdentifier = this.signingTokenParameters.CreateKeyIdentifierClause(this.elementContainer.SourceSigningToken, tokenReferenceStyle);
         if (tokenToDeriveIdentifier == null)
         {
             throw TraceUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("TokenManagerCannotCreateTokenReference")), base.Message);
         }
         if (this.signingTokenParameters.RequireDerivedKeys && !this.signingTokenParameters.HasAsymmetricKey)
         {
             string signatureKeyDerivationAlgorithm = base.AlgorithmSuite.GetSignatureKeyDerivationAlgorithm(this.elementContainer.SourceSigningToken, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
             string keyDerivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(base.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
             if (signatureKeyDerivationAlgorithm != keyDerivationAlgorithm)
             {
                 throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(System.ServiceModel.SR.GetString("UnsupportedCryptoAlgorithm", new object[] { signatureKeyDerivationAlgorithm })));
             }
             DerivedKeySecurityToken token2 = new DerivedKeySecurityToken(-1, 0, base.AlgorithmSuite.GetSignatureKeyDerivationLength(this.elementContainer.SourceSigningToken, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, this.elementContainer.SourceSigningToken, tokenToDeriveIdentifier, signatureKeyDerivationAlgorithm, this.GenerateId());
             sourceSigningToken = this.elementContainer.DerivedSigningToken = token2;
             clause2 = new LocalIdKeyIdentifierClause(sourceSigningToken.Id, sourceSigningToken.GetType());
         }
         else
         {
             sourceSigningToken = this.elementContainer.SourceSigningToken;
             clause2 = tokenToDeriveIdentifier;
         }
         SecurityKeyIdentifier identifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[] { clause2 });
         if ((this.signatureConfirmationsToSend != null) && (this.signatureConfirmationsToSend.Count > 0))
         {
             ISecurityElement[] elementArray = this.CreateSignatureConfirmationElements(this.signatureConfirmationsToSend);
             for (int i = 0; i < elementArray.Length; i++)
             {
                 SendSecurityHeaderElement confirmation = new SendSecurityHeaderElement(elementArray[i].Id, elementArray[i]) {
                     MarkedForEncryption = this.signatureConfirmationsToSend.IsMarkedForEncryption
                 };
                 this.elementContainer.AddSignatureConfirmation(confirmation);
             }
         }
         bool generateTargettablePrimarySignature = (this.endorsingTokenParameters != null) || (this.signedEndorsingTokenParameters != null);
         this.StartPrimarySignatureCore(sourceSigningToken, identifier, this.signatureParts, generateTargettablePrimarySignature);
     }
 }
 private void StartEncryption()
 {
     if (this.elementContainer.SourceEncryptionToken != null)
     {
         SecurityToken sourceEncryptionToken;
         SecurityKeyIdentifierClause clause2;
         SecurityKeyIdentifierClause clause3;
         SecurityKeyIdentifier identifier;
         SecurityTokenReferenceStyle tokenReferenceStyle = this.GetTokenReferenceStyle(this.encryptingTokenParameters);
         bool flag = tokenReferenceStyle == SecurityTokenReferenceStyle.Internal;
         SecurityKeyIdentifierClause clause = this.encryptingTokenParameters.CreateKeyIdentifierClause(this.elementContainer.SourceEncryptionToken, tokenReferenceStyle);
         if (clause == null)
         {
             throw TraceUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("TokenManagerCannotCreateTokenReference")), base.Message);
         }
         if (!System.ServiceModel.Security.SecurityUtils.HasSymmetricSecurityKey(this.elementContainer.SourceEncryptionToken))
         {
             string str;
             XmlDictionaryString str2;
             int keyLength = Math.Max(0x80, base.AlgorithmSuite.DefaultSymmetricKeyLength);
             System.ServiceModel.Security.CryptoHelper.ValidateSymmetricKeyLength(keyLength, base.AlgorithmSuite);
             byte[] buffer = new byte[keyLength / 8];
             System.ServiceModel.Security.CryptoHelper.FillRandomBytes(buffer);
             base.AlgorithmSuite.GetKeyWrapAlgorithm(this.elementContainer.SourceEncryptionToken, out str, out str2);
             WrappedKeySecurityToken token2 = new WrappedKeySecurityToken(this.GenerateId(), buffer, str, str2, this.elementContainer.SourceEncryptionToken, new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[] { clause }));
             this.elementContainer.WrappedEncryptionToken = token2;
             sourceEncryptionToken = token2;
             clause2 = new LocalIdKeyIdentifierClause(token2.Id, token2.GetType());
             flag = true;
         }
         else
         {
             sourceEncryptionToken = this.elementContainer.SourceEncryptionToken;
             clause2 = clause;
         }
         if (this.encryptingTokenParameters.RequireDerivedKeys)
         {
             string encryptionKeyDerivationAlgorithm = base.AlgorithmSuite.GetEncryptionKeyDerivationAlgorithm(sourceEncryptionToken, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
             string keyDerivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(base.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
             if (encryptionKeyDerivationAlgorithm != keyDerivationAlgorithm)
             {
                 throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(System.ServiceModel.SR.GetString("UnsupportedCryptoAlgorithm", new object[] { encryptionKeyDerivationAlgorithm })));
             }
             DerivedKeySecurityToken token3 = new DerivedKeySecurityToken(-1, 0, base.AlgorithmSuite.GetEncryptionKeyDerivationLength(sourceEncryptionToken, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, sourceEncryptionToken, clause2, encryptionKeyDerivationAlgorithm, this.GenerateId());
             this.encryptingToken = this.elementContainer.DerivedEncryptionToken = token3;
             clause3 = new LocalIdKeyIdentifierClause(token3.Id, token3.GetType());
         }
         else
         {
             this.encryptingToken = sourceEncryptionToken;
             clause3 = clause2;
         }
         this.skipKeyInfoForEncryption = ((flag && base.EncryptedKeyContainsReferenceList) && (this.encryptingToken is WrappedKeySecurityToken)) && this.signThenEncrypt;
         if (this.skipKeyInfoForEncryption)
         {
             identifier = null;
         }
         else
         {
             identifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[] { clause3 });
         }
         this.StartEncryptionCore(this.encryptingToken, identifier);
     }
 }
 private void SignWithSupportingTokens()
 {
     SecurityToken[] endorsingSupportingTokens = this.elementContainer.GetEndorsingSupportingTokens();
     if (endorsingSupportingTokens != null)
     {
         for (int i = 0; i < endorsingSupportingTokens.Length; i++)
         {
             SecurityToken token2;
             SecurityKeyIdentifierClause clause2;
             SecurityToken token = endorsingSupportingTokens[i];
             SecurityKeyIdentifierClause tokenToDeriveIdentifier = this.endorsingTokenParameters[i].CreateKeyIdentifierClause(token, this.GetTokenReferenceStyle(this.endorsingTokenParameters[i]));
             if (tokenToDeriveIdentifier == null)
             {
                 throw TraceUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("TokenManagerCannotCreateTokenReference")), base.Message);
             }
             if (this.endorsingTokenParameters[i].RequireDerivedKeys && !this.endorsingTokenParameters[i].HasAsymmetricKey)
             {
                 string keyDerivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(base.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
                 DerivedKeySecurityToken token3 = new DerivedKeySecurityToken(-1, 0, base.AlgorithmSuite.GetSignatureKeyDerivationLength(token, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, token, tokenToDeriveIdentifier, keyDerivationAlgorithm, this.GenerateId());
                 token2 = token3;
                 clause2 = new LocalIdKeyIdentifierClause(token3.Id, token3.GetType());
                 this.elementContainer.AddEndorsingDerivedSupportingToken(token3);
             }
             else
             {
                 token2 = token;
                 clause2 = tokenToDeriveIdentifier;
             }
             this.SignWithSupportingToken(token2, clause2);
         }
     }
     SecurityToken[] signedEndorsingSupportingTokens = this.elementContainer.GetSignedEndorsingSupportingTokens();
     if (signedEndorsingSupportingTokens != null)
     {
         for (int j = 0; j < signedEndorsingSupportingTokens.Length; j++)
         {
             SecurityToken token5;
             SecurityKeyIdentifierClause clause4;
             SecurityToken token4 = signedEndorsingSupportingTokens[j];
             SecurityKeyIdentifierClause clause3 = this.signedEndorsingTokenParameters[j].CreateKeyIdentifierClause(token4, this.GetTokenReferenceStyle(this.signedEndorsingTokenParameters[j]));
             if (clause3 == null)
             {
                 throw TraceUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("TokenManagerCannotCreateTokenReference")), base.Message);
             }
             if (this.signedEndorsingTokenParameters[j].RequireDerivedKeys && !this.signedEndorsingTokenParameters[j].HasAsymmetricKey)
             {
                 string derivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(base.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
                 DerivedKeySecurityToken token6 = new DerivedKeySecurityToken(-1, 0, base.AlgorithmSuite.GetSignatureKeyDerivationLength(token4, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, token4, clause3, derivationAlgorithm, this.GenerateId());
                 token5 = token6;
                 clause4 = new LocalIdKeyIdentifierClause(token6.Id, token6.GetType());
                 this.elementContainer.AddSignedEndorsingDerivedSupportingToken(token6);
             }
             else
             {
                 token5 = token4;
                 clause4 = clause3;
             }
             this.SignWithSupportingToken(token5, clause4);
         }
     }
 }
 void SignWithSupportingTokens()
 {
     SecurityToken[] endorsingTokens = this.elementContainer.GetEndorsingSupportingTokens();
     if (endorsingTokens != null)
     {
         for (int i = 0; i < endorsingTokens.Length; ++i)
         {
             SecurityToken source = endorsingTokens[i];
             SecurityKeyIdentifierClause sourceKeyClause = endorsingTokenParameters[i].CreateKeyIdentifierClause(source, GetTokenReferenceStyle(endorsingTokenParameters[i]));
             if (sourceKeyClause == null)
             {
                 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message);
             }
             SecurityToken signingToken;
             SecurityKeyIdentifierClause signingKeyClause;
             if (endorsingTokenParameters[i].RequireDerivedKeys && !endorsingTokenParameters[i].HasAsymmetricKey)
             {
                 string derivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
                 DerivedKeySecurityToken dkt = new DerivedKeySecurityToken(-1, 0, 
                     this.AlgorithmSuite.GetSignatureKeyDerivationLength(source, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null,
                     DerivedKeySecurityToken.DefaultNonceLength, source, sourceKeyClause, derivationAlgorithm, GenerateId());
                 signingToken = dkt;
                 signingKeyClause = new LocalIdKeyIdentifierClause(dkt.Id, dkt.GetType());
                 this.elementContainer.AddEndorsingDerivedSupportingToken(dkt);
             }
             else
             {
                 signingToken = source;
                 signingKeyClause = sourceKeyClause;
             }
             SignWithSupportingToken(signingToken, signingKeyClause);
         }
     }
     SecurityToken[] signedEndorsingSupportingTokens = this.elementContainer.GetSignedEndorsingSupportingTokens();
     if (signedEndorsingSupportingTokens != null)
     {
         for (int i = 0; i < signedEndorsingSupportingTokens.Length; ++i)
         {
             SecurityToken source = signedEndorsingSupportingTokens[i];
             SecurityKeyIdentifierClause sourceKeyClause = signedEndorsingTokenParameters[i].CreateKeyIdentifierClause(source, GetTokenReferenceStyle(signedEndorsingTokenParameters[i]));
             if (sourceKeyClause == null)
             {
                 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message);
             }
             SecurityToken signingToken;
             SecurityKeyIdentifierClause signingKeyClause;
             if (signedEndorsingTokenParameters[i].RequireDerivedKeys && !signedEndorsingTokenParameters[i].HasAsymmetricKey)
             {
                 string derivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
                 DerivedKeySecurityToken dkt = new DerivedKeySecurityToken(-1, 0, 
                     this.AlgorithmSuite.GetSignatureKeyDerivationLength(source, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null,
                     DerivedKeySecurityToken.DefaultNonceLength, source, sourceKeyClause, derivationAlgorithm, GenerateId());
                 signingToken = dkt;
                 signingKeyClause = new LocalIdKeyIdentifierClause(dkt.Id, dkt.GetType());
                 this.elementContainer.AddSignedEndorsingDerivedSupportingToken(dkt);
             }
             else
             {
                 signingToken = source;
                 signingKeyClause = sourceKeyClause;
             }
             SignWithSupportingToken(signingToken, signingKeyClause);
         }
     }
 }
        void StartSignature()
        {
            if (this.elementContainer.SourceSigningToken == null)
            {
                return;
            }

            // determine the key identifier clause to use for the source
            SecurityTokenReferenceStyle sourceSigningKeyReferenceStyle = GetTokenReferenceStyle(this.signingTokenParameters);
            SecurityKeyIdentifierClause sourceSigningKeyIdentifierClause = this.signingTokenParameters.CreateKeyIdentifierClause(this.elementContainer.SourceSigningToken, sourceSigningKeyReferenceStyle);
            if (sourceSigningKeyIdentifierClause == null)
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message);
            }

            SecurityToken signingToken;
            SecurityKeyIdentifierClause signingKeyIdentifierClause;

            // determine if a token needs to be derived
            if (this.signingTokenParameters.RequireDerivedKeys && !this.signingTokenParameters.HasAsymmetricKey)
            {
                string derivationAlgorithm = this.AlgorithmSuite.GetSignatureKeyDerivationAlgorithm(this.elementContainer.SourceSigningToken, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
                string expectedDerivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
                if (derivationAlgorithm == expectedDerivationAlgorithm)
                {
                    DerivedKeySecurityToken derivedSigningToken = new DerivedKeySecurityToken(-1, 0, this.AlgorithmSuite.GetSignatureKeyDerivationLength(this.elementContainer.SourceSigningToken, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, this.elementContainer.SourceSigningToken,
                        sourceSigningKeyIdentifierClause, derivationAlgorithm, GenerateId());
                    signingToken = this.elementContainer.DerivedSigningToken = derivedSigningToken;
                    signingKeyIdentifierClause = new LocalIdKeyIdentifierClause(signingToken.Id, signingToken.GetType());
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedCryptoAlgorithm, derivationAlgorithm)));
                }
            }
            else
            {
                signingToken = elementContainer.SourceSigningToken;
                signingKeyIdentifierClause = sourceSigningKeyIdentifierClause;
            }

            SecurityKeyIdentifier signingKeyIdentifier = new SecurityKeyIdentifier(signingKeyIdentifierClause);
            
            if (signatureConfirmationsToSend != null && signatureConfirmationsToSend.Count > 0)
            {
                ISecurityElement[] signatureConfirmationElements;
                signatureConfirmationElements = CreateSignatureConfirmationElements(signatureConfirmationsToSend);
                for (int i = 0; i < signatureConfirmationElements.Length; ++i)
                {
                    SendSecurityHeaderElement sigConfElement = new SendSecurityHeaderElement(signatureConfirmationElements[i].Id, signatureConfirmationElements[i]);
                    sigConfElement.MarkedForEncryption = signatureConfirmationsToSend.IsMarkedForEncryption;
                    this.elementContainer.AddSignatureConfirmation(sigConfElement);
                }
            }

            bool generateTargettablePrimarySignature = ((this.endorsingTokenParameters != null) || (this.signedEndorsingTokenParameters != null));
            this.StartPrimarySignatureCore(signingToken, signingKeyIdentifier, this.signatureParts, generateTargettablePrimarySignature);
        }
        void StartEncryption()
        {
            if (this.elementContainer.SourceEncryptionToken == null)
            {
                return;
            }
            // determine the key identifier clause to use for the source
            SecurityTokenReferenceStyle sourceEncryptingKeyReferenceStyle = GetTokenReferenceStyle(this.encryptingTokenParameters);
            bool encryptionTokenSerialized = sourceEncryptingKeyReferenceStyle == SecurityTokenReferenceStyle.Internal;
            SecurityKeyIdentifierClause sourceEncryptingKeyIdentifierClause = this.encryptingTokenParameters.CreateKeyIdentifierClause(this.elementContainer.SourceEncryptionToken, sourceEncryptingKeyReferenceStyle);
            if (sourceEncryptingKeyIdentifierClause == null)
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message);
            }
            SecurityToken sourceToken;
            SecurityKeyIdentifierClause sourceTokenIdentifierClause;

            // if the source token cannot do symmetric crypto, create a wrapped key
            if (!SecurityUtils.HasSymmetricSecurityKey(elementContainer.SourceEncryptionToken))
            {
                int keyLength = Math.Max(128, this.AlgorithmSuite.DefaultSymmetricKeyLength);
                CryptoHelper.ValidateSymmetricKeyLength(keyLength, this.AlgorithmSuite);
                byte[] key = new byte[keyLength / 8];
                CryptoHelper.FillRandomBytes(key);
                string keyWrapAlgorithm;
                XmlDictionaryString keyWrapAlgorithmDictionaryString;
                this.AlgorithmSuite.GetKeyWrapAlgorithm(elementContainer.SourceEncryptionToken, out keyWrapAlgorithm, out keyWrapAlgorithmDictionaryString);
                WrappedKeySecurityToken wrappedKey = new WrappedKeySecurityToken(GenerateId(), key, keyWrapAlgorithm, keyWrapAlgorithmDictionaryString,
                    elementContainer.SourceEncryptionToken, new SecurityKeyIdentifier(sourceEncryptingKeyIdentifierClause));
                elementContainer.WrappedEncryptionToken = wrappedKey;
                sourceToken = wrappedKey;
                sourceTokenIdentifierClause = new LocalIdKeyIdentifierClause(wrappedKey.Id, wrappedKey.GetType());
                encryptionTokenSerialized = true;
            }
            else
            {
                sourceToken = elementContainer.SourceEncryptionToken;
                sourceTokenIdentifierClause = sourceEncryptingKeyIdentifierClause;
            }

            // determine if a key needs to be derived
            SecurityKeyIdentifierClause encryptingKeyIdentifierClause;
            // determine if a token needs to be derived
            if (this.encryptingTokenParameters.RequireDerivedKeys)
            {
                string derivationAlgorithm = this.AlgorithmSuite.GetEncryptionKeyDerivationAlgorithm(sourceToken, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
                string expectedDerivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.StandardsManager.MessageSecurityVersion.SecureConversationVersion);
                if (derivationAlgorithm == expectedDerivationAlgorithm)
                {
                    DerivedKeySecurityToken derivedEncryptingToken = new DerivedKeySecurityToken(-1, 0,
                        this.AlgorithmSuite.GetEncryptionKeyDerivationLength(sourceToken, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, sourceToken, sourceTokenIdentifierClause, derivationAlgorithm, GenerateId());
                    this.encryptingToken = this.elementContainer.DerivedEncryptionToken = derivedEncryptingToken;
                    encryptingKeyIdentifierClause = new LocalIdKeyIdentifierClause(derivedEncryptingToken.Id, derivedEncryptingToken.GetType());
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedCryptoAlgorithm, derivationAlgorithm)));
                }
            }
            else
            {
                this.encryptingToken = sourceToken;
                encryptingKeyIdentifierClause = sourceTokenIdentifierClause;
            }

            this.skipKeyInfoForEncryption = encryptionTokenSerialized && this.EncryptedKeyContainsReferenceList && (this.encryptingToken is WrappedKeySecurityToken) && this.signThenEncrypt;
            SecurityKeyIdentifier identifier;
            if (this.skipKeyInfoForEncryption)
            {
                identifier = null;
            }
            else
            {
                identifier = new SecurityKeyIdentifier(encryptingKeyIdentifierClause);
            }

            StartEncryptionCore(this.encryptingToken, identifier);
        }
Beispiel #16
0
 DerivedKeySecurityToken CreateDerivedKey (string id, 
                                                   SecurityKeyIdentifierClause actualClause, 
                                                   SymmetricAlgorithm actualKey)
 {
     RijndaelManaged deriv = new RijndaelManaged ();
     deriv.KeySize = security.Element.DefaultAlgorithmSuite.DefaultEncryptionKeyDerivationLength;
     deriv.Mode = CipherMode.CBC;
     deriv.Padding = PaddingMode.ISO10126;
     deriv.GenerateKey ();
     var dkeyToken = new DerivedKeySecurityToken (
         id,
         null, // algorithm
         actualClause,
         new InMemorySymmetricSecurityKey (actualKey.Key),
         null, // name
         null, // generation
         null, // offset
         deriv.Key.Length,
         null, // label
         deriv.Key);
     return dkeyToken;
 }
		public Message SecureMessage ()
		{
			secprop = Message.Properties.Security ?? new SecurityMessageProperty ();

			SecurityToken encToken =
				secprop.InitiatorToken != null ? secprop.InitiatorToken.SecurityToken : security.EncryptionToken;
			// FIXME: it might be still incorrect.
			SecurityToken signToken =
				Parameters == CounterParameters ? null :
				security.SigningToken;
			MessageProtectionOrder protectionOrder =
				security.MessageProtectionOrder;
			SecurityTokenSerializer serializer =
				security.TokenSerializer;
			SecurityBindingElement element =
				security.Element;
			SecurityAlgorithmSuite suite = element.DefaultAlgorithmSuite;

// FIXME: remove this hack
if (!ShouldOutputEncryptedKey)
	encToken = new BinarySecretSecurityToken (secprop.EncryptionKey);

			string messageId = "uuid-" + Guid.NewGuid ();
			int identForMessageId = 1;
			XmlDocument doc = new XmlDocument ();
			doc.PreserveWhitespace = true;

			UniqueId relatesTo = RelatesTo;
			if (relatesTo != null)
				msg.Headers.RelatesTo = relatesTo;
			else // FIXME: probably it is always added when it is stateful ?
				msg.Headers.MessageId = new UniqueId ("urn:" + messageId);

			// FIXME: get correct ReplyTo value
			if (Direction == MessageDirection.Input)
				msg.Headers.ReplyTo = new EndpointAddress (Constants.WsaAnonymousUri);

			if (MessageTo != null)
				msg.Headers.To = MessageTo.Uri;

			// wss:Security
			WSSecurityMessageHeader header =
				new WSSecurityMessageHeader (serializer);
			msg.Headers.Add (header);
			// 1. [Timestamp]
			if (element.IncludeTimestamp) {
				WsuTimestamp timestamp = new WsuTimestamp ();
				timestamp.Id = messageId + "-" + identForMessageId++;
				timestamp.Created = DateTime.Now;
				// FIXME: on service side, use element.LocalServiceSettings.TimestampValidityDuration
				timestamp.Expires = timestamp.Created.Add (element.LocalClientSettings.TimestampValidityDuration);
				header.AddContent (timestamp);
			}

			XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable);
			nsmgr.AddNamespace ("s", msg.Version.Envelope.Namespace);
			nsmgr.AddNamespace ("o", Constants.WssNamespace);
			nsmgr.AddNamespace ("u", Constants.WsuNamespace);
			nsmgr.AddNamespace ("o11", Constants.Wss11Namespace);

			/*WrappedKey*/SecurityToken primaryToken = null;
			DerivedKeySecurityToken dkeyToken = null;
			SecurityToken actualToken = null;
			SecurityKeyIdentifierClause actualClause = null;
			Signature sig = null;

			List<DerivedKeySecurityToken> derivedKeys =
				new List<DerivedKeySecurityToken> ();

			SymmetricAlgorithm masterKey = new RijndaelManaged ();
			masterKey.KeySize = suite.DefaultSymmetricKeyLength;
			masterKey.Mode = CipherMode.CBC;
			masterKey.Padding = PaddingMode.ISO10126;
			SymmetricAlgorithm actualKey = masterKey;

			// 2. [Encryption Token]

			// SecurityTokenInclusionMode
			// - Initiator or Recipient
			// - done or notyet. FIXME: not implemented yet
			// It also affects on key reference output

			bool includeEncToken = // /* FIXME: remove this hack */Parameters is SslSecurityTokenParameters ? false :
						ShouldIncludeToken (
				Security.RecipientParameters.InclusionMode, false);
			bool includeSigToken = // /* FIXME: remove this hack */ Parameters is SslSecurityTokenParameters ? false :
						ShouldIncludeToken (
				Security.InitiatorParameters.InclusionMode, false);

			SecurityKeyIdentifierClause encClause = ShouldOutputEncryptedKey ?
				CounterParameters.CallCreateKeyIdentifierClause (encToken, !ShouldOutputEncryptedKey ? SecurityTokenReferenceStyle.Internal : includeEncToken ? Parameters.ReferenceStyle : SecurityTokenReferenceStyle.External) : null;

			MessagePartSpecification sigSpec = SignaturePart;
			MessagePartSpecification encSpec = EncryptionPart;

			// encryption key (possibly also used for signing)
			// FIXME: get correct SymmetricAlgorithm according to the algorithm suite
			if (secprop.EncryptionKey != null)
				actualKey.Key = secprop.EncryptionKey;

// FIXME: remove thid hack
if (!ShouldOutputEncryptedKey)
primaryToken = RequestContext.RequestMessage.Properties.Security.ProtectionToken.SecurityToken as WrappedKeySecurityToken;
else
			primaryToken =
				// FIXME: remove this hack?
				encToken is SecurityContextSecurityToken ? encToken :
				new WrappedKeySecurityToken (messageId + "-" + identForMessageId++,
				actualKey.Key,
				// security.DefaultKeyWrapAlgorithm,
				Parameters.InternalHasAsymmetricKey ?
					suite.DefaultAsymmetricKeyWrapAlgorithm :
					suite.DefaultSymmetricKeyWrapAlgorithm,
				encToken,
				encClause != null ? new SecurityKeyIdentifier (encClause) : null);

			// If it reuses request's encryption key, do not output.
			if (ShouldOutputEncryptedKey)
				header.AddContent (primaryToken);

			actualToken = primaryToken;

			// FIXME: I doubt it is correct...
			WrappedKeySecurityToken requestEncKey = ShouldOutputEncryptedKey ? null : primaryToken as WrappedKeySecurityToken;
			actualClause = requestEncKey == null ? (SecurityKeyIdentifierClause)
				new LocalIdKeyIdentifierClause (actualToken.Id, typeof (WrappedKeySecurityToken)) :
				new InternalEncryptedKeyIdentifierClause (SHA1.Create ().ComputeHash (requestEncKey.GetWrappedKey ()));

			// generate derived key if needed
			if (CounterParameters.RequireDerivedKeys) {
				RijndaelManaged deriv = new RijndaelManaged ();
				deriv.KeySize = suite.DefaultEncryptionKeyDerivationLength;
				deriv.Mode = CipherMode.CBC;
				deriv.Padding = PaddingMode.ISO10126;
				deriv.GenerateKey ();
				dkeyToken = new DerivedKeySecurityToken (
					GenerateId (doc),
					null, // algorithm
					actualClause,
					new InMemorySymmetricSecurityKey (actualKey.Key),
					null, // name
					null, // generation
					null, // offset
					deriv.Key.Length,
					null, // label
					deriv.Key);
				derivedKeys.Add (dkeyToken);
				actualToken = dkeyToken;
				actualKey.Key = ((SymmetricSecurityKey) dkeyToken.SecurityKeys [0]).GetSymmetricKey ();
				actualClause = new LocalIdKeyIdentifierClause (dkeyToken.Id);
				header.AddContent (dkeyToken);
			}

			ReferenceList refList = new ReferenceList ();
			// When encrypted with DerivedKeyToken, put references
			// immediately after the derived token (not inside the
			// primary token).
			// Similarly, when we do not output EncryptedKey,
			// output ReferenceList in the same way.
			if (CounterParameters.RequireDerivedKeys ||
			    !ShouldOutputEncryptedKey)
				header.AddContent (refList);
			else
				((WrappedKeySecurityToken) primaryToken).ReferenceList = refList;

			// [Signature Confirmation]
			if (security.RequireSignatureConfirmation && secprop.ConfirmedSignatures.Count > 0)
				foreach (string value in secprop.ConfirmedSignatures)
					header.AddContent (new Wss11SignatureConfirmation (GenerateId (doc), value));

			SupportingTokenInfoCollection tokenInfos =
				Direction == MessageDirection.Input ?
				security.CollectSupportingTokens (GetAction ()) :
				new SupportingTokenInfoCollection (); // empty

			foreach (SupportingTokenInfo tinfo in tokenInfos)
				header.AddContent (tinfo.Token);

			// populate DOM to sign.
			XPathNavigator nav = doc.CreateNavigator ();
			using (XmlWriter w = nav.AppendChild ()) {
				msg.WriteMessage (w);
			}

			XmlElement body = doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement;
			string bodyId = null;
			XmlElement secElem = null;
			Collection<WSSignedXml> endorsedSignatures =
				new Collection<WSSignedXml> ();
			bool signatureProtection = (protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature);

			// Below are o:Security contents that are not signed...
			if (includeSigToken && signToken != null)
				header.AddContent (signToken);

			switch (protectionOrder) {
			case MessageProtectionOrder.EncryptBeforeSign:
				// FIXME: implement
				throw new NotImplementedException ();
			case MessageProtectionOrder.SignBeforeEncrypt:
			case MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature:

				// sign
				// see clause 8 of WS-SecurityPolicy C.2.2
				WSSignedXml sxml = new WSSignedXml (doc);
				SecurityTokenReferenceKeyInfo sigKeyInfo;

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

				// encrypt

				WSEncryptedXml exml = new WSEncryptedXml (doc);

				EncryptedData edata = Encrypt (body, actualKey, actualToken.Id, refList, actualClause, exml, doc);
				EncryptedXml.ReplaceElement (body, edata, false);

				// encrypt signature
				if (signatureProtection) {
					XmlElement sigxml = sig.GetXml ();
					edata = Encrypt (sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc);
					header.AddContent (edata);

					foreach (WSSignedXml ssxml in endorsedSignatures) {
						sigxml = ssxml.GetXml ();
						edata = Encrypt (sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc);
						header.AddContent (edata);
					}

					if (security.RequireSignatureConfirmation) {
						Collection<Wss11SignatureConfirmation> confs = header.FindAll<Wss11SignatureConfirmation> ();
						int count = 0;
						foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) {
							edata = Encrypt (elem, actualKey, confs [count].Id, refList, actualClause, exml, doc);
							EncryptedXml.ReplaceElement (elem, edata, false);
							header.Contents.Insert (header.Contents.IndexOf (confs [count]), edata);
							header.Contents.Remove (confs [count++]);
						}
					}
				}

				// encrypt Encrypted supporting tokens
				foreach (SupportingTokenInfo tinfo in tokenInfos) {
					if (tinfo.Mode == SecurityTokenAttachmentMode.SignedEncrypted) {
						XmlElement el = exml.GetIdElement (doc, tinfo.Token.Id);
						tinfo.Encrypted = Encrypt (el, actualKey, actualToken.Id, refList, actualClause, exml, doc);
						EncryptedXml.ReplaceElement (el, tinfo.Encrypted, false);
						header.Contents.Insert (header.Contents.IndexOf (tinfo.Token), tinfo.Encrypted);
						header.Contents.Remove (tinfo.Token);
					}
				}
				break;
			}

			Message ret = new WSSecurityMessage (Message.CreateMessage (msg.Version, msg.Headers.Action, new XmlNodeReader (doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement)), bodyId);
			ret.Properties.Security = (SecurityMessageProperty) secprop.CreateCopy ();
			ret.Properties.Security.EncryptionKey = masterKey.Key;

			// FIXME: can we support TransportToken here?
			if (element is AsymmetricSecurityBindingElement) {
				ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification (encToken, null); // FIXME: second argument
				ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification (signToken, null); // FIXME: second argument
			}
			else
				ret.Properties.Security.ProtectionToken = new SecurityTokenSpecification (primaryToken, null);

			ret.Headers.Clear ();
			ret.Headers.CopyHeadersFrom (msg);

			// Header contents are:
			//	- Timestamp
			//	- SignatureConfirmation if required
			//	- EncryptionToken if included
			//	- derived key token for EncryptionToken
			//	- ReferenceList for encrypted items
			//	- signed supporting tokens
			//	- signed endorsing supporting tokens
			//	(i.e. Signed/SignedEncrypted/SignedEndorsing)
			//	- Signature Token if different from enc token.
			//	- derived key token for sig token if different
			//	- Signature for:
			//		- Timestamp
			//		- supporting tokens (regardless of
			//		  its inclusion)
			//		- message parts in SignedParts
			//		- SignatureToken if TokenProtection
			//		  (regardless of its inclusion)
			//	- Signatures for the main signature (above),
			//	  for every endorsing token and signed
			//	  endorsing token.
			//	

//MessageBuffer zzz = ret.CreateBufferedCopy (100000);
//ret = zzz.CreateMessage ();
//Console.WriteLine (zzz.CreateMessage ());
			return ret;
		}
 public void SetOutgoingSessionToken(SecurityToken token)
 {
     if (token == null)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
     }
     lock (this.ThisLock)
     {
         this.outgoingSessionToken = token;
         if (this.requireDerivedKeys)
         {
             string keyDerivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(this.sessionStandardsManager.MessageSecurityVersion.SecureConversationVersion);
             this.derivedSignatureToken = new DerivedKeySecurityToken(-1, 0, this.Factory.OutgoingAlgorithmSuite.GetSignatureKeyDerivationLength(token, this.sessionStandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, token, this.Factory.SecurityTokenParameters.CreateKeyIdentifierClause(token, SecurityTokenReferenceStyle.External), keyDerivationAlgorithm, System.ServiceModel.Security.SecurityUtils.GenerateId());
             this.derivedEncryptionToken = new DerivedKeySecurityToken(-1, 0, this.Factory.OutgoingAlgorithmSuite.GetEncryptionKeyDerivationLength(token, this.sessionStandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, token, this.Factory.SecurityTokenParameters.CreateKeyIdentifierClause(token, SecurityTokenReferenceStyle.External), keyDerivationAlgorithm, System.ServiceModel.Security.SecurityUtils.GenerateId());
         }
     }
 }