internal static SecurityToken ResolveSecurityToken(SecurityKeyIdentifier ski, SecurityTokenResolver tokenResolver)
        {
            SecurityToken token = null;

            if (tokenResolver != null)
            {
                tokenResolver.TryResolveToken(ski, out token);
            }

            if (token == null)
            {
                // Check if this is a RSA key.
                RsaKeyIdentifierClause rsaClause;
                if (ski.TryFind <RsaKeyIdentifierClause>(out rsaClause))
                {
                    token = new RsaSecurityToken(rsaClause.Rsa);
                }
            }

            if (token == null)
            {
                // Check if this is a X509RawDataKeyIdentifier Clause.
                X509RawDataKeyIdentifierClause rawDataKeyIdentifierClause;
                if (ski.TryFind <X509RawDataKeyIdentifierClause>(out rawDataKeyIdentifierClause))
                {
                    token = new X509SecurityToken(new X509Certificate2(rawDataKeyIdentifierClause.GetX509RawData()));
                }
            }

            return(token);
        }
 /// <summary>
 /// Constructs an encrypting credential based on the x509 token.
 /// </summary>
 /// <param name="token">The x509 security token.</param>
 internal X509EncryptingCredentials(X509SecurityToken token)
     : this(
     token,
     new SecurityKeyIdentifier(token.CreateKeyIdentifierClause<X509IssuerSerialKeyIdentifierClause>()),
     SecurityAlgorithms.DefaultAsymmetricKeyWrapAlgorithm)
 {
 }
        void Context_PostAuthenticateRequest(object sender, EventArgs e)
        {
            var context = ((HttpApplication)sender).Context;

            // no need to call transformation if session already exists
            if (FederatedAuthentication.SessionAuthenticationModule != null &&
                FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(context.Request.Cookies))
            {
                return;
            }

            var transformer = FederatedAuthentication.ServiceConfiguration.ClaimsAuthenticationManager;
            if (transformer != null)
            {
                var principal = context.User as ClaimsPrincipal;

                if (context.Request.ClientCertificate.IsPresent && context.Request.ClientCertificate.IsValid)
                {
                    var cert = new X509Certificate2(context.Request.ClientCertificate.Certificate);
                    var token = new X509SecurityToken(cert);
                    var certId = new HttpsSecurityTokenHandler().ValidateToken(token).First();

                    principal.Identities.Add(certId);
                }

                var transformedPrincipal = transformer.Authenticate(context.Request.RawUrl, principal);

                context.User = transformedPrincipal;
                Thread.CurrentPrincipal = transformedPrincipal;
            }
        }
        /// <summary>
        /// Returns the issuer name of the given X509SecurityToken mapping the Certificate Thumbprint to
        /// a name in the configured map.
        /// </summary>
        /// <param name="securityToken">SecurityToken for which the issuer name is requested.</param>
        /// <returns>Issuer name if the token was registered, null otherwise.</returns>
        /// <exception cref="ArgumentNullException">The input parameter 'securityToken' is null.</exception>
        public override string GetIssuerName(SecurityToken securityToken)
        {
            if (securityToken == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("securityToken");
            }

            X509SecurityToken x509SecurityToken = securityToken as X509SecurityToken;

            if (x509SecurityToken != null)
            {
                string thumbprint = x509SecurityToken.Certificate.Thumbprint;
                if (_configuredTrustedIssuers.ContainsKey(thumbprint))
                {
                    string issuerName = _configuredTrustedIssuers[thumbprint];
                    issuerName = string.IsNullOrEmpty(issuerName) ? x509SecurityToken.Certificate.Subject : issuerName;

                    if (TD.GetIssuerNameSuccessIsEnabled())
                    {
                        TD.GetIssuerNameSuccess(EventTraceActivity.GetFromThreadOrCreate(), issuerName, securityToken.Id);
                    }

                    return(issuerName);
                }
            }

            if (TD.GetIssuerNameFailureIsEnabled())
            {
                TD.GetIssuerNameFailure(EventTraceActivity.GetFromThreadOrCreate(), securityToken.Id);
            }

            return(null);
        }
Example #5
0
		public void MatchesKeyIdentifierClause ()
		{
			UniqueId id = new UniqueId ();
			X509SecurityToken t = new X509SecurityToken (cert, id.ToString ());
			LocalIdKeyIdentifierClause l =
				new LocalIdKeyIdentifierClause (id.ToString ());
			Assert.IsTrue (t.MatchesKeyIdentifierClause (l), "#1-1");

			l = new LocalIdKeyIdentifierClause ("#" + id.ToString ());
			Assert.IsFalse (t.MatchesKeyIdentifierClause (l), "#1-2");

			X509ThumbprintKeyIdentifierClause h =
				new X509ThumbprintKeyIdentifierClause (cert);
			Assert.IsTrue (t.MatchesKeyIdentifierClause (h), "#2-1");

			h = new X509ThumbprintKeyIdentifierClause (cert2);
			Assert.IsFalse (t.MatchesKeyIdentifierClause (h), "#2-2");

			X509IssuerSerialKeyIdentifierClause i =
				new X509IssuerSerialKeyIdentifierClause (cert);
			Assert.IsTrue (t.MatchesKeyIdentifierClause (i), "#3-1");

			i = new X509IssuerSerialKeyIdentifierClause (cert2);
			Assert.IsFalse (t.MatchesKeyIdentifierClause (i), "#3-2");

			X509RawDataKeyIdentifierClause s =
				new X509RawDataKeyIdentifierClause (cert);
			Assert.IsTrue (t.MatchesKeyIdentifierClause (s), "#4-1");

			s = new X509RawDataKeyIdentifierClause (cert2);
			Assert.IsFalse (t.MatchesKeyIdentifierClause (s), "#4-2");
		}
Example #6
0
        /// <summary>
        /// Writes the X509SecurityToken to the given XmlWriter.
        /// </summary>
        /// <param name="writer">XmlWriter to write the token into.</param>
        /// <param name="token">The SecurityToken of type X509SecurityToken to be written.</param>
        /// <exception cref="ArgumentNullException">The parameter 'writer' or 'token' is null.</exception>
        /// <exception cref="ArgumentException">The token is not of type X509SecurityToken.</exception>
        public override void WriteToken(XmlWriter writer, SecurityToken token)
        {
            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

            if (token == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
            }

            X509SecurityToken x509Token = token as X509SecurityToken;

            if (x509Token == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("token", SR.GetString(SR.ID0018, typeof(X509SecurityToken)));
            }

            writer.WriteStartElement(WSSecurity10Constants.Elements.BinarySecurityToken, WSSecurity10Constants.Namespace);
            if (!String.IsNullOrEmpty(x509Token.Id))
            {
                writer.WriteAttributeString(WSSecurityUtilityConstants.Attributes.Id, WSSecurityUtilityConstants.Namespace, x509Token.Id);
            }

            writer.WriteAttributeString(WSSecurity10Constants.Attributes.ValueType, null, WSSecurity10Constants.X509TokenType);
            writer.WriteAttributeString(WSSecurity10Constants.Attributes.EncodingType, WSSecurity10Constants.Base64EncodingType);

            byte[] rawData = x509Token.Certificate.GetRawCertData();
            writer.WriteBase64(rawData, 0, rawData.Length);
            writer.WriteEndElement();
        }
 /// <summary>
 /// Constructs an encrypting credential based on the x509 token.
 /// </summary>
 /// <param name="token">The x509 security token.</param>
 internal X509EncryptingCredentials(X509SecurityToken token)
     : this(
         token,
         new SecurityKeyIdentifier(token.CreateKeyIdentifierClause <X509IssuerSerialKeyIdentifierClause>()),
         SecurityAlgorithms.DefaultAsymmetricKeyWrapAlgorithm)
 {
 }
 /// <summary>
 /// Utility method to get a X509 Token from a given certificate
 /// </summary>
 /// <param name="storeName">Name of certificate store (e.g. My, TrustedPeople)</param>
 /// <param name="storeLocation">Location of certificate store (e.g. LocalMachine, CurrentUser)</param>
 /// <param name="subjectDistinguishedName">The Subject Distinguished Name of the certificate</param>
 /// <returns>The corresponding X509 Token</returns>
 public static X509SecurityToken GetX509TokenFromCert(StoreName storeName,
                                                      StoreLocation storeLocation,
                                                      string subjectDistinguishedName)
 {
     X509Certificate2 certificate = LookupCertificate(storeName, storeLocation, subjectDistinguishedName);
     X509SecurityToken t = new X509SecurityToken(certificate);
     return t;
 }
        /// <summary>
        /// Constructor for X509SigningCredentials based on an x509 token and the security key identifier to be used.
        /// It uses the token's public key, its default asymmetric signature algorithm and the specified security key identifier
        /// </summary>
        /// <param name="token">The x509 security token.</param>
        /// <param name="ski">The security key identifier to be used.</param>
        /// <param name="signatureAlgorithm">signature algorithm</param>
        /// <param name="digestAlgorithm">digest algorithm</param>
        internal X509SigningCredentials(X509SecurityToken token, SecurityKeyIdentifier ski, string signatureAlgorithm, string digestAlgorithm)
            : base(token.SecurityKeys[0], signatureAlgorithm, digestAlgorithm, ski)
        {
            this.certificate = token.Certificate;

            if (!this.certificate.HasPrivateKey)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("token", SR.GetString(SR.ID2057));
            }
        }
Example #10
0
		public void DefaultValues ()
		{
			UniqueId id = new UniqueId ();
			X509SecurityToken t = new X509SecurityToken (cert, id.ToString ());
			Assert.AreEqual (id.ToString (), t.Id, "#1");
			Assert.AreEqual (cert, t.Certificate, "#2");
			Assert.AreEqual (cert.NotBefore.ToUniversalTime (), t.ValidFrom, "#3");
			Assert.AreEqual (cert.NotAfter.ToUniversalTime (), t.ValidTo, "#4");
			Assert.AreEqual (1, t.SecurityKeys.Count, "#5");
		}
        private KeyDescriptor GetSigningKeyDescriptor()
        {
            var certificate = _options.SigningCertificate;

            var clause = new X509SecurityToken(certificate).CreateKeyIdentifierClause<X509RawDataKeyIdentifierClause>();
            var key = new KeyDescriptor(new SecurityKeyIdentifier(clause));
            key.Use = KeyType.Signing;

            return key;
        }
		WrappedKeySecurityToken GetReferent ()
		{
			string id = "referent";
			byte [] key = new byte [32];
			X509SecurityToken token = new X509SecurityToken (cert);
			SecurityKeyIdentifierClause kic =
				new X509ThumbprintKeyIdentifierClause (cert);
			string alg = SecurityAlgorithms.RsaOaepKeyWrap;
			return new WrappedKeySecurityToken (id, key, alg, token,
				new SecurityKeyIdentifier (kic));
		}
		public void AddDecryptingToken(X509Certificate2 certificate) {
			Contract.Requires<ArgumentNullException>(certificate != null);
			Contract.Requires<ArgumentException>(certificate.HasPrivateKey);
			var cert = new X509SecurityToken(certificate);
			try {
				this.AddDecryptingToken(cert);
			} catch {
				cert.Dispose();
				throw;
			}
		}
		public void Properties ()
		{
			X509ThumbprintKeyIdentifierClause ic =
				new X509ThumbprintKeyIdentifierClause (cert);
			Assert.AreEqual (cert.GetCertHash (), ic.GetX509Thumbprint (), "#1-1");
			Assert.AreEqual (null, ic.ClauseType, "#1-2");

			ic = new X509SecurityToken (cert).CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause> ();
			Assert.AreEqual (cert.GetCertHash (), ic.GetX509Thumbprint (), "#2-1");
			Assert.AreEqual (null, ic.ClauseType, "#2-2");
		}
		public void AddDecryptingToken(X509Certificate2 certificate) {
			Requires.NotNull(certificate, "certificate");
			Requires.True(certificate.HasPrivateKey, "certificate");
			var cert = new X509SecurityToken(certificate);
			try {
				this.AddDecryptingToken(cert);
			} catch {
				cert.Dispose();
				throw;
			}
		}
 private static TokenValidationParameters GetValidationParameters()
 {
     var bytes = Convert.FromBase64String(_securityKey.Value);
     var token = new X509SecurityToken(new X509Certificate2(bytes));
     return new TokenValidationParameters
     {
         ValidAudience = _authority + "/resources",
         ValidIssuer = _authority,
         IssuerSigningKeyResolver = (arbitrarily, declaring, these, parameters) => { return token.SecurityKeys.First(); },
         IssuerSigningToken = token
     };
 }
 public X509CertTokenVerificationKey(X509Certificate2 cert)
 {
     lock (_lock)
         {
             if (_x509Certificate == null)
             {
                 _x509Certificate = cert;
                 _securityToken = new X509SecurityToken(_x509Certificate);
                 base.RawBody = _x509Certificate.RawData;
             }
         }
 }
 SspiNegotiationTokenProviderState CreateTlsSspiState(X509SecurityToken token)
 {
     X509Certificate2 clientCertificate;
     if (token == null)
     {
         clientCertificate = null;
     }
     else 
     {
         clientCertificate = token.Certificate;
     }
     TlsSspiNegotiation tlsNegotiation = new TlsSspiNegotiation(String.Empty, SchProtocols.Ssl3Client | SchProtocols.TlsClient, clientCertificate);
     return new SspiNegotiationTokenProviderState(tlsNegotiation);
 }
        /// <summary>
        /// Validates the token using the wrapped token handler and generates IAuthorizationPolicy
        /// wrapping the returned ClaimsIdentities.
        /// </summary>
        /// <param name="token">Token to be validated.</param>
        /// <returns>Read-only collection of IAuthorizationPolicy</returns>
        protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore( SecurityToken token )
        {
            ReadOnlyCollection<ClaimsIdentity> identities = null;
            try
            {
                identities = _wrappedX509SecurityTokenHandler.ValidateToken(token);
            }
            catch ( Exception ex )
            {
                if ( !_exceptionMapper.HandleSecurityTokenProcessingException( ex ) )
                {
                    throw;
                }
            }

            // tlsnego will dispose of the x509, when we write out the bootstrap we will get a dispose error.

            bool shouldSaveBootstrapContext = SecurityTokenHandlerConfiguration.DefaultSaveBootstrapContext;
            if ( _wrappedX509SecurityTokenHandler.Configuration != null )
            {
                shouldSaveBootstrapContext = _wrappedX509SecurityTokenHandler.Configuration.SaveBootstrapContext;
            }

            if ( shouldSaveBootstrapContext )
            {
                X509SecurityToken x509Token = token as X509SecurityToken;
                SecurityToken tokenToCache;
                if ( x509Token != null )
                {
                    tokenToCache = new X509SecurityToken( x509Token.Certificate );
                }
                else
                {
                    tokenToCache = token;
                }

                BootstrapContext bootstrapContext = new BootstrapContext(tokenToCache, _wrappedX509SecurityTokenHandler);
                foreach (ClaimsIdentity identity in identities)
                {
                    identity.BootstrapContext = bootstrapContext;
                }
            }

            List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1);
            policies.Add(new AuthorizationPolicy(identities));

            return policies.AsReadOnly();
        }
 public override SecurityMessageProperty GetRemoteSecurity()
 {
     if (this.clientSecurity.TransportToken != null)
     {
         return this.clientSecurity;
     }
     if (this.clientCertificate != null)
     {
         SecurityToken token = new X509SecurityToken(this.clientCertificate);
         ReadOnlyCollection<IAuthorizationPolicy> tokenPolicies = System.ServiceModel.Security.SecurityUtils.NonValidatingX509Authenticator.ValidateToken(token);
         this.clientSecurity = new SecurityMessageProperty();
         this.clientSecurity.TransportToken = new SecurityTokenSpecification(token, tokenPolicies);
         this.clientSecurity.ServiceSecurityContext = new ServiceSecurityContext(tokenPolicies);
         return this.clientSecurity;
     }
     return base.GetRemoteSecurity();
 }
 public override void OnAbort()
 {
     if (this.serverTokenProvider != null)
     {
         System.ServiceModel.Security.SecurityUtils.AbortTokenProviderIfRequired(this.serverTokenProvider);
         this.serverTokenProvider = null;
     }
     if (this.clientTokenAuthenticator != null)
     {
         System.ServiceModel.Security.SecurityUtils.AbortTokenAuthenticatorIfRequired(this.clientTokenAuthenticator);
         this.clientTokenAuthenticator = null;
     }
     if (this.serverToken != null)
     {
         this.serverToken = null;
     }
     base.OnAbort();
 }
Example #22
0
        /// <summary>
        /// Creates a SAML assertion based on a symmetric proof key
        /// </summary>
        /// <param name="claims">A ClaimSet containing the claims to be placed into the SAML assertion</param>
        /// <param name="signatureToken">An X509SecurityToken that will be used to sign the SAML assertion</param>
        /// <param name="encryptionToken">An X509SecurityToken that will be used to encrypt the proof key</param>
        /// <param name="proofToken">A BinarySecretSecurityToken containing the proof key</param>
        /// <param name="algoSuite">The algorithm suite to use when performing cryptographic operations</param>
        /// <returns>A SAML assertion containing the passed in claims and proof key, signed by the provided signature token</returns>
        public static SamlAssertion CreateSymmetricKeyBasedAssertion(ClaimSet claims, X509SecurityToken signatureToken, X509SecurityToken encryptionToken, BinarySecretSecurityToken proofToken, SecurityAlgorithmSuite algoSuite)
        {
            // Check various input parameters
            if (claims == null)
                throw new ArgumentNullException("claims");

            if (claims.Count == 0)
                throw new ArgumentException("Provided ClaimSet must contain at least one claim");

            if (proofToken == null)
                throw new ArgumentNullException("proofToken");

            if (signatureToken == null)
                throw new ArgumentNullException("signatureToken");

            if (encryptionToken == null)
                throw new ArgumentNullException("encryptionToken");

            if (proofToken == null)
                throw new ArgumentNullException("proofToken");

            if (algoSuite == null)
                throw new ArgumentNullException("algoSuite");

            // Get signing key and a key identifier for same
            SecurityKey signatureKey = signatureToken.SecurityKeys[0];
            SecurityKeyIdentifierClause signatureSkic = signatureToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>();
            SecurityKeyIdentifier signatureKeyIdentifier  = new SecurityKeyIdentifier(signatureSkic);

            // Get encryption key and a key identifier for same
            SecurityKey encryptionKey = encryptionToken.SecurityKeys[0];
            SecurityKeyIdentifierClause encryptionSkic = encryptionToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>();
            SecurityKeyIdentifier encryptionKeyIdentifier = new SecurityKeyIdentifier(encryptionSkic);

            // Encrypt the proof key and create a key identifier for same
            byte[] proofKey = proofToken.GetKeyBytes();
            byte[] encryptedSecret = new byte[proofKey.Length];
            encryptedSecret = encryptionKey.EncryptKey(algoSuite.DefaultAsymmetricKeyWrapAlgorithm, proofKey);
            SecurityKeyIdentifier proofKeyIdentifier = new SecurityKeyIdentifier(new EncryptedKeyIdentifierClause(encryptedSecret, algoSuite.DefaultAsymmetricKeyWrapAlgorithm, encryptionKeyIdentifier));

            // Create the assertion
            return CreateAssertion(claims, signatureKey, signatureKeyIdentifier, proofKeyIdentifier, algoSuite);
        }
 public override void OnClose(TimeSpan timeout)
 {
     TimeoutHelper helper = new TimeoutHelper(timeout);
     if (this.serverTokenProvider != null)
     {
         System.ServiceModel.Security.SecurityUtils.CloseTokenProviderIfRequired(this.serverTokenProvider, helper.RemainingTime());
         this.serverTokenProvider = null;
     }
     if (this.clientTokenAuthenticator != null)
     {
         System.ServiceModel.Security.SecurityUtils.CloseTokenAuthenticatorIfRequired(this.clientTokenAuthenticator, helper.RemainingTime());
         this.clientTokenAuthenticator = null;
     }
     if (this.serverToken != null)
     {
         this.serverToken = null;
     }
     base.OnClose(helper.RemainingTime());
 }
        internal static SecurityToken ResolveSecurityToken(SecurityKeyIdentifier ski, SecurityTokenResolver tokenResolver)
        {
            SecurityToken                  token = null;
            RsaKeyIdentifierClause         clause;
            X509RawDataKeyIdentifierClause clause2;

            if (tokenResolver != null)
            {
                tokenResolver.TryResolveToken(ski, out token);
            }
            if ((token == null) && ski.TryFind <RsaKeyIdentifierClause>(out clause))
            {
                token = new RsaSecurityToken(clause.Rsa);
            }
            if ((token == null) && ski.TryFind <X509RawDataKeyIdentifierClause>(out clause2))
            {
                token = new X509SecurityToken(new X509Certificate2(clause2.GetX509RawData()));
            }
            return(token);
        }
Example #25
0
        /// <summary>
        /// Inherited from <see cref="SecurityTokenResolver"/>.
        /// </summary>
        protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
        {
            if (keyIdentifierClause == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
            }

            token = null;

            //
            // Try raw X509
            //
            X509RawDataKeyIdentifierClause rawDataClause = keyIdentifierClause as X509RawDataKeyIdentifierClause;

            if (rawDataClause != null)
            {
                token = new X509SecurityToken(new X509Certificate2(rawDataClause.GetX509RawData()));
                return(true);
            }

            //
            // Try RSA
            //
            RsaKeyIdentifierClause rsaClause = keyIdentifierClause as RsaKeyIdentifierClause;

            if (rsaClause != null)
            {
                token = new RsaSecurityToken(rsaClause.Rsa);
                return(true);
            }

            if (_wrappedTokenResolver.TryResolveToken(keyIdentifierClause, out token))
            {
                return(true);
            }

            return(false);
        }
 /// <summary>
 /// Constructs an encrypting credential based on the x509 token, key wrapping algorithm, and security key identifier.
 /// </summary>
 /// <param name="token">The x509 security token.</param>
 /// <param name="ski">The security key identifier to be used.</param>
 /// <param name="keyWrappingAlgorithm">The key wrapping al----htm.</param>
 internal X509EncryptingCredentials(X509SecurityToken token, SecurityKeyIdentifier ski, string keyWrappingAlgorithm)
     : base(token.SecurityKeys[0], ski, keyWrappingAlgorithm)
 {
     this.certificate = token.Certificate;
 }
 /// <summary>
 /// Constructs an encrypting credential based on the x509 token and key wrapping algorithm.
 /// </summary>
 /// <param name="token">The x509 security token.</param>
 /// <param name="keyWrappingAlgorithm">The key wrapping al----htm.</param>
 internal X509EncryptingCredentials(X509SecurityToken token, string keyWrappingAlgorithm)
     : this(token, new SecurityKeyIdentifier(token.CreateKeyIdentifierClause <X509IssuerSerialKeyIdentifierClause>()), keyWrappingAlgorithm)
 {
 }
        /// <summary>
        /// Resolves the given SecurityKeyIdentifierClause to a SecurityToken.
        /// </summary>
        /// <param name="keyIdentifierClause">SecurityKeyIdentifierClause to resolve.</param>
        /// <param name="token">The resolved SecurityToken.</param>
        /// <returns>True if successfully resolved.</returns>
        /// <exception cref="ArgumentNullException">The input argument 'keyIdentifierClause' is null.</exception>
        protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
        {
            if (keyIdentifierClause == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
            }

            token = null;
            X509Store store = null;
            X509Certificate2Collection certs = null;

            try
            {
                store = new X509Store(this.storeName, this.storeLocation);
                store.Open(OpenFlags.ReadOnly);
                certs = store.Certificates;
                foreach (X509Certificate2 cert in certs)
                {
                    X509ThumbprintKeyIdentifierClause thumbprintKeyIdentifierClause = keyIdentifierClause as X509ThumbprintKeyIdentifierClause;
                    if (thumbprintKeyIdentifierClause != null && thumbprintKeyIdentifierClause.Matches(cert))
                    {
                        token = new X509SecurityToken(cert);
                        return(true);
                    }

                    X509IssuerSerialKeyIdentifierClause issuerSerialKeyIdentifierClause = keyIdentifierClause as X509IssuerSerialKeyIdentifierClause;
                    if (issuerSerialKeyIdentifierClause != null && issuerSerialKeyIdentifierClause.Matches(cert))
                    {
                        token = new X509SecurityToken(cert);
                        return(true);
                    }

                    X509SubjectKeyIdentifierClause subjectKeyIdentifierClause = keyIdentifierClause as X509SubjectKeyIdentifierClause;
                    if (subjectKeyIdentifierClause != null && subjectKeyIdentifierClause.Matches(cert))
                    {
                        token = new X509SecurityToken(cert);
                        return(true);
                    }

                    X509RawDataKeyIdentifierClause rawDataKeyIdentifierClause = keyIdentifierClause as X509RawDataKeyIdentifierClause;
                    if (rawDataKeyIdentifierClause != null && rawDataKeyIdentifierClause.Matches(cert))
                    {
                        token = new X509SecurityToken(cert);
                        return(true);
                    }
                }
            }
            finally
            {
                if (certs != null)
                {
                    for (int i = 0; i < certs.Count; i++)
                    {
                        certs[i].Reset();
                    }
                }

                if (store != null)
                {
                    store.Close();
                }
            }

            return(false);
        }
        public virtual ClaimsPrincipal AuthenticateClientCertificate(X509Certificate2 certificate)
        {
            SecurityTokenHandlerCollection handlers;
            var token = new X509SecurityToken(certificate);

            if (Configuration.TryGetClientCertificateMapping(out handlers))
            {
                var identity = handlers.First().ValidateToken(token);
                return new ClaimsPrincipal(identity);
            }

            return Principal.Anonymous;
        }
 private bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
 {
     X509Certificate2 certificate2 = new X509Certificate2(certificate);
     SecurityToken token = new X509SecurityToken(certificate2, false);
     ReadOnlyCollection<IAuthorizationPolicy> tokenPolicies = this.serverCertificateAuthenticator.ValidateToken(token);
     this.serverSecurity = new SecurityMessageProperty();
     this.serverSecurity.TransportToken = new SecurityTokenSpecification(token, tokenPolicies);
     this.serverSecurity.ServiceSecurityContext = new ServiceSecurityContext(tokenPolicies);
     AuthorizationContext authorizationContext = this.serverSecurity.ServiceSecurityContext.AuthorizationContext;
     this.parent.IdentityVerifier.EnsureOutgoingIdentity(base.RemoteAddress, base.Via, authorizationContext);
     return true;
 }
        private static bool Matches(SecurityKeyIdentifierClause keyIdentifierClause, SecurityKey key, CertMatcher certMatcher, out SecurityToken token)
        {
            token = null;
            if (certMatcher != null)
            {
                X509SecurityKey x509Key = key as X509SecurityKey;
                if (x509Key != null)
                {
                    if (certMatcher(x509Key.Certificate))
                    {
                        token = new X509SecurityToken(x509Key.Certificate);
                        return true;
                    }
                }
                else
                {
                    X509AsymmetricSecurityKey x509AsymmKey = key as X509AsymmetricSecurityKey;
                    if (x509AsymmKey != null)
                    {
                        X509Certificate2 cert = _certFieldInfo.GetValue(x509AsymmKey) as X509Certificate2;
                        if (cert != null && certMatcher(cert))
                        {
                            token = new X509SecurityToken(cert);
                            return true;
                        }
                    }
                }
            }

            return false;
        }
        /// <summary>
        /// Updates properties in the <see cref="SecurityTokenHandlerConfiguration"/> objects for the 
        /// <see cref="SecurityTokenHandlerCollection"/> objects contained in 
        /// <see cref="IdentityConfiguration.SecurityTokenHandlerCollectionManager"/> to be consistent with the property
        /// values on this <see cref="IdentityConfiguration"/> instance.
        /// </summary>
        /// <remarks>
        /// This method should be invoked prior to using these token handlers
        /// for token processing.
        /// </remarks>
        /// <exception cref="InvalidOperationException">If this method is invoked more than once.</exception>
        public virtual void Initialize()
        {
            if (this.IsInitialized)
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID7009));
            }

            SecurityTokenHandlerCollection defaultCollection = this.SecurityTokenHandlers;

            if (!object.ReferenceEquals(_serviceHandlerConfiguration, defaultCollection.Configuration))
            {
                //
                // If someone has created their own new STHConfig and set it as default, leave that config alone.
                //
                TraceUtility.TraceString(TraceEventType.Information, SR.GetString(SR.ID4283));
                this.IsInitialized = true;
                return;
            }

            // Update the ServiceTokenResolver of the default TokenHandlerCollection's configuration, if serviceCertificate is set.
            if (this.ServiceCertificate != null)
            {
                SecurityTokenResolver serviceCertificateResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(new ReadOnlyCollection<SecurityToken>(
                                                      new SecurityToken[] { new X509SecurityToken(this.ServiceCertificate) }), false);

                SecurityTokenResolver tokenResolver = this.SecurityTokenHandlers.Configuration.ServiceTokenResolver;

                if ((tokenResolver != null) && (tokenResolver != EmptySecurityTokenResolver.Instance))
                {
                    this.SecurityTokenHandlers.Configuration.ServiceTokenResolver = new AggregateTokenResolver(new SecurityTokenResolver[] { serviceCertificateResolver, tokenResolver });
                }
                else
                {
                    this.SecurityTokenHandlers.Configuration.ServiceTokenResolver = serviceCertificateResolver;
                }
            }

            SecurityTokenResolver configuredIssuerTokenResolver = this.IssuerTokenResolver;

            if (this.IssuerTokenResolver == SecurityTokenHandlerConfiguration.DefaultIssuerTokenResolver)
            {
                //
                // Add the known certificates from WCF's ServiceCredentials in front of 
                // the default issuer token resolver.
                //
                if (this.KnownIssuerCertificates != null)
                {
                    int count = this.KnownIssuerCertificates.Count;
                    if (count > 0)
                    {
                        SecurityToken[] tokens = new SecurityToken[count];
                        for (int i = 0; i < count; i++)
                        {
                            tokens[i] = new X509SecurityToken(this.KnownIssuerCertificates[i]);
                        }

                        SecurityTokenResolver knownCertificateTokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(new ReadOnlyCollection<SecurityToken>(tokens), false);
                        
                        this.IssuerTokenResolver = new AggregateTokenResolver(new SecurityTokenResolver[] { knownCertificateTokenResolver, configuredIssuerTokenResolver });                       
                    }
                }
            }
            
            if (this.CertificateValidationMode != X509CertificateValidationMode.Custom)
            {
                defaultCollection.Configuration.CertificateValidator = X509Util.CreateCertificateValidator(defaultCollection.Configuration.CertificateValidationMode,
                                                                                                            defaultCollection.Configuration.RevocationMode,
                                                                                                            defaultCollection.Configuration.TrustedStoreLocation);
            }
            else if (object.ReferenceEquals(defaultCollection.Configuration.CertificateValidator, SecurityTokenHandlerConfiguration.DefaultCertificateValidator))
            {
                //
                // If the mode is custom but the validator or still default, something has gone wrong.
                //
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4280)));
            }

            this.IsInitialized = true;
        }
Example #33
0
        /// <summary>
        /// Validates an <see cref="X509SecurityToken"/>.
        /// </summary>
        /// <param name="token">The <see cref="X509SecurityToken"/> to validate.</param>
        /// <returns>A <see cref="ReadOnlyCollection{T}"/> of <see cref="ClaimsIdentity"/> representing the identities contained in the token.</returns>
        /// <exception cref="ArgumentNullException">The parameter 'token' is null.</exception>
        /// <exception cref="ArgumentException">The token is not assignable from <see cref="X509SecurityToken"/>.</exception>
        /// <exception cref="InvalidOperationException">Configuration <see cref="SecurityTokenHandlerConfiguration"/>is null.</exception>
        /// <exception cref="SecurityTokenValidationException">The current <see cref="X509CertificateValidator"/> was unable to validate the certificate in the Token.</exception>
        /// <exception cref="InvalidOperationException">Configuration.IssuerNameRegistry is null.</exception>
        /// <exception cref="SecurityTokenException">Configuration.IssuerNameRegistry return null when resolving the issuer of the certificate in the Token.</exception>
        public override ReadOnlyCollection <ClaimsIdentity> ValidateToken(SecurityToken token)
        {
            if (token == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
            }

            X509SecurityToken x509Token = token as X509SecurityToken;

            if (x509Token == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("token", SR.GetString(SR.ID0018, typeof(X509SecurityToken)));
            }

            if (this.Configuration == null)
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4274));
            }

            try
            {
                // Validate the token.
                try
                {
                    this.CertificateValidator.Validate(x509Token.Certificate);
                }
                catch (SecurityTokenValidationException e)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.ID4257,
                                                                                                                                X509Util.GetCertificateId(x509Token.Certificate)), e));
                }

                if (this.Configuration.IssuerNameRegistry == null)
                {
                    throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4277));
                }

                string issuer = X509Util.GetCertificateIssuerName(x509Token.Certificate, this.Configuration.IssuerNameRegistry);
                if (String.IsNullOrEmpty(issuer))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID4175)));
                }

                ClaimsIdentity identity = null;

                if (!mapToWindows)
                {
                    identity = new ClaimsIdentity(AuthenticationTypes.X509);

                    // PARTIAL TRUST: will fail when adding claims, AddClaim is SecurityCritical.
                    identity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.X509));
                }
                else
                {
                    WindowsIdentity          windowsIdentity;
                    X509WindowsSecurityToken x509WindowsSecurityToken = token as X509WindowsSecurityToken;

                    // if this is the case, then the user has already been mapped to a windows account, just return the identity after adding a couple of claims.
                    if (x509WindowsSecurityToken != null && x509WindowsSecurityToken.WindowsIdentity != null)
                    {
                        // X509WindowsSecurityToken is disposable, make a copy.
                        windowsIdentity = new WindowsIdentity(x509WindowsSecurityToken.WindowsIdentity.Token, x509WindowsSecurityToken.AuthenticationType);
                    }
                    else
                    {
                        // Ensure NT_AUTH chain policy for certificate account mapping
                        if (this.x509NTAuthChainTrustValidator == null)
                        {
                            lock (this.lockObject)
                            {
                                if (this.x509NTAuthChainTrustValidator == null)
                                {
                                    this.x509NTAuthChainTrustValidator = new X509NTAuthChainTrustValidator();
                                }
                            }
                        }

                        this.x509NTAuthChainTrustValidator.Validate(x509Token.Certificate);
                        windowsIdentity = ClaimsHelper.CertificateLogon(x509Token.Certificate);
                    }

                    // PARTIAL TRUST: will fail when adding claims, AddClaim is SecurityCritical.
                    windowsIdentity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.X509));
                    identity = windowsIdentity;
                }

                if (this.Configuration.SaveBootstrapContext)
                {
                    identity.BootstrapContext = new BootstrapContext(token, this);
                }

                identity.AddClaim(new Claim(ClaimTypes.AuthenticationInstant, XmlConvert.ToString(DateTime.UtcNow, DateTimeFormats.Generated), ClaimValueTypes.DateTime));
                identity.AddClaims(X509Util.GetClaimsFromCertificate(x509Token.Certificate, issuer));

                this.TraceTokenValidationSuccess(token);

                List <ClaimsIdentity> identities = new List <ClaimsIdentity>(1);
                identities.Add(identity);
                return(identities.AsReadOnly());
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                this.TraceTokenValidationFailure(token, e.Message);
                throw e;
            }
        }
        private KeyDescriptor GetEncryptionDescriptor(X509Certificate2 certificate)
        {
            var clause = new X509SecurityToken(certificate).CreateKeyIdentifierClause<X509RawDataKeyIdentifierClause>();
            var key = new KeyDescriptor(new SecurityKeyIdentifier(clause));
            key.Use = KeyType.Encryption;

            return key;
        }
        /// <summary>
        /// Inherited from <see cref="SecurityTokenResolver"/>.
        /// </summary>
        protected override bool TryResolveTokenCore( SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token )
        {
            if ( keyIdentifierClause == null )
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "keyIdentifierClause" );
            }

            token = null;

            //
            // Try raw X509
            //
            X509RawDataKeyIdentifierClause rawDataClause = keyIdentifierClause as X509RawDataKeyIdentifierClause;
            if ( rawDataClause != null )
            {
                token = new X509SecurityToken( new X509Certificate2( rawDataClause.GetX509RawData() ) );
                return true;
            }

            //
            // Try RSA
            //
            RsaKeyIdentifierClause rsaClause = keyIdentifierClause as RsaKeyIdentifierClause;
            if ( rsaClause != null )
            {
                token = new RsaSecurityToken( rsaClause.Rsa );
                return true;
            }

            if ( _wrappedTokenResolver.TryResolveToken( keyIdentifierClause, out token ) )
            {
                return true;
            }
            
            return false;
        }
Example #36
0
        /// <summary>
        /// Creates a SAML token for the specified email address.
        /// </summary>
        public static UserIdentity CreateSAMLToken(string emailAddress)
        {
            // Normally this would be done by a server that is capable of verifying that
            // the user is a legimate holder of email address. Using a local certficate to
            // signed the SAML token is a short cut that would never be done in a real system.
            CertificateIdentifier userid = new CertificateIdentifier();

            userid.StoreType = CertificateStoreType.Windows;
            userid.StorePath = "LocalMachine\\My";
            userid.SubjectName = "UA Sample Client";

            X509Certificate2 certificate = userid.Find();
            X509SecurityToken signingToken = new X509SecurityToken(certificate);

            // Create list of confirmation strings
            List<string> confirmations = new List<string>();

            // Add holder-of-key string to list of confirmation strings
            confirmations.Add("urn:oasis:names:tc:SAML:1.0:cm:bearer");

            // Create SAML subject statement based on issuer member variable, confirmation string collection 
            // local variable and proof key identifier parameter
            SamlSubject subject = new SamlSubject("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", null, emailAddress);

            // Create a list of SAML attributes
            List<SamlAttribute> attributes = new List<SamlAttribute>();
            Claim claim = Claim.CreateNameClaim(emailAddress);
            attributes.Add(new SamlAttribute(claim));

            // Create list of SAML statements
            List<SamlStatement> statements = new List<SamlStatement>();

            // Add a SAML attribute statement to the list of statements. Attribute statement is based on 
            // subject statement and SAML attributes resulting from claims
            statements.Add(new SamlAttributeStatement(subject, attributes));

            // Create a valid from/until condition
            DateTime validFrom = DateTime.UtcNow;
            DateTime validTo = DateTime.UtcNow.AddHours(12);

            SamlConditions conditions = new SamlConditions(validFrom, validTo);

            // Create the SAML assertion
            SamlAssertion assertion = new SamlAssertion(
                "_" + Guid.NewGuid().ToString(),
                signingToken.Certificate.Subject,
                validFrom,
                conditions,
                null,
                statements);

            SecurityKey signingKey = new System.IdentityModel.Tokens.RsaSecurityKey((RSA)signingToken.Certificate.PrivateKey);

            // Set the signing credentials for the SAML assertion
            assertion.SigningCredentials = new SigningCredentials(
                signingKey,
                System.IdentityModel.Tokens.SecurityAlgorithms.RsaSha1Signature,
                System.IdentityModel.Tokens.SecurityAlgorithms.Sha1Digest,
                new SecurityKeyIdentifier(signingToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>()));

            return new UserIdentity(new SamlSecurityToken(assertion));
        }
        private void ParseToken(string xmlToken, X509Certificate2 cert)
        {
            int skew = 300; // default to 5 minutes
            string tokenskew = System.Configuration.ConfigurationManager.AppSettings["MaximumClockSkew"];
            if (!string.IsNullOrEmpty(tokenskew))
                skew = Int32.Parse(tokenskew);

            XmlReader tokenReader = new XmlTextReader(new StringReader(xmlToken));
            EncryptedData enc = new EncryptedData();

            enc.TokenSerializer = WSSecurityTokenSerializer.DefaultInstance;

            enc.ReadFrom(tokenReader);

            List<SecurityToken> tokens = new List<SecurityToken>();
            SecurityToken encryptingToken = new X509SecurityToken(cert);
            tokens.Add(encryptingToken);

            SecurityTokenResolver tokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(tokens.AsReadOnly(), false);
            SymmetricSecurityKey encryptingCrypto;

            // an error here usually means that you have selected the wrong key.
            encryptingCrypto = (SymmetricSecurityKey)tokenResolver.ResolveSecurityKey(enc.KeyIdentifier[0]);

            SymmetricAlgorithm algorithm = encryptingCrypto.GetSymmetricAlgorithm(enc.EncryptionMethod);

            byte[] decryptedData = enc.GetDecryptedBuffer(algorithm);

            SecurityTokenSerializer tokenSerializer = WSSecurityTokenSerializer.DefaultInstance;
            XmlReader reader = new XmlTextReader(new StreamReader(new MemoryStream(decryptedData), Encoding.UTF8));

            m_token = (SamlSecurityToken)tokenSerializer.ReadToken(reader, tokenResolver);

            SamlSecurityTokenAuthenticator authenticator = new SamlSecurityTokenAuthenticator(new List<SecurityTokenAuthenticator>(
                                                            new SecurityTokenAuthenticator[]{
                                                                new RsaSecurityTokenAuthenticator(),
                                                                new X509SecurityTokenAuthenticator() }), new TimeSpan(0, 0, skew));

            if (authenticator.CanValidateToken(m_token))
            {
                ReadOnlyCollection<IAuthorizationPolicy> policies = authenticator.ValidateToken(m_token);
                m_authorizationContext = AuthorizationContext.CreateDefaultAuthorizationContext(policies);
                m_identityClaims = FindIdentityClaims(m_authorizationContext);
            }
            else
            {
                throw new Exception("Unable to validate the token.");
            }
        }
Example #38
0
 public SecurityTokenService(string issuerName)
 {
     issuer = issuerName;
     issuerToken = GetToken(issuerName, StoreName.My, StoreLocation.LocalMachine);
 }
 internal override void Open(TimeSpan timeout)
 {
     TimeoutHelper helper = new TimeoutHelper(timeout);
     base.Open(helper.RemainingTime());
     if (this.clientCertificateProvider != null)
     {
         System.ServiceModel.Security.SecurityUtils.OpenTokenProviderIfRequired(this.clientCertificateProvider, helper.RemainingTime());
         this.clientToken = (X509SecurityToken) this.clientCertificateProvider.GetToken(helper.RemainingTime());
     }
 }
        /// <summary>
        /// Resolves the given SecurityKeyIdentifierClause to a SecurityToken.
        /// </summary>
        /// <param name="keyIdentifierClause">SecurityKeyIdentifierClause to resolve.</param>
        /// <param name="token">The resolved SecurityToken.</param>
        /// <returns>True if successfully resolved.</returns>
        /// <exception cref="ArgumentNullException">The input argument 'keyIdentifierClause' is null.</exception>
        protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
        {
            if (keyIdentifierClause == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
            }

            token = null;
            X509Store store = null;
            X509Certificate2Collection certs = null;
            try
            {
                store = new X509Store(this.storeName, this.storeLocation);
                store.Open(OpenFlags.ReadOnly);
                certs = store.Certificates;
                foreach (X509Certificate2 cert in certs)
                {
                    X509ThumbprintKeyIdentifierClause thumbprintKeyIdentifierClause = keyIdentifierClause as X509ThumbprintKeyIdentifierClause;
                    if (thumbprintKeyIdentifierClause != null && thumbprintKeyIdentifierClause.Matches(cert))
                    {
                        token = new X509SecurityToken(cert);
                        return true;
                    }

                    X509IssuerSerialKeyIdentifierClause issuerSerialKeyIdentifierClause = keyIdentifierClause as X509IssuerSerialKeyIdentifierClause;
                    if (issuerSerialKeyIdentifierClause != null && issuerSerialKeyIdentifierClause.Matches(cert))
                    {
                        token = new X509SecurityToken(cert);
                        return true;
                    }

                    X509SubjectKeyIdentifierClause subjectKeyIdentifierClause = keyIdentifierClause as X509SubjectKeyIdentifierClause;
                    if (subjectKeyIdentifierClause != null && subjectKeyIdentifierClause.Matches(cert))
                    {
                        token = new X509SecurityToken(cert);
                        return true;
                    }

                    X509RawDataKeyIdentifierClause rawDataKeyIdentifierClause = keyIdentifierClause as X509RawDataKeyIdentifierClause;
                    if (rawDataKeyIdentifierClause != null && rawDataKeyIdentifierClause.Matches(cert))
                    {
                        token = new X509SecurityToken(cert);
                        return true;
                    }
                }
            }
            finally
            {
                if (certs != null)
                {
                    for (int i = 0; i < certs.Count; i++)
                    {
                        certs[i].Reset();
                    }
                }

                if (store != null)
                {
                    store.Close();
                }
            }

            return false;
        }
        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;
        }