private SecurityToken ResolveSignatureToken(SecurityKeyIdentifier keyIdentifier, SecurityTokenResolver resolver, bool isPrimarySignature)
        {
            SecurityToken          token;
            RsaKeyIdentifierClause clause;

            TryResolveKeyIdentifier(keyIdentifier, resolver, true, out token);
            if (((token == null) && !isPrimarySignature) && ((keyIdentifier.Count == 1) && keyIdentifier.TryFind <RsaKeyIdentifierClause>(out clause)))
            {
                RsaSecurityTokenAuthenticator tokenAuthenticator = base.FindAllowedAuthenticator <RsaSecurityTokenAuthenticator>(false);
                if (tokenAuthenticator != null)
                {
                    SupportingTokenAuthenticatorSpecification specification;
                    token = new RsaSecurityToken(clause.Rsa);
                    ReadOnlyCollection <IAuthorizationPolicy> onlys = tokenAuthenticator.ValidateToken(token);
                    TokenTracker supportingTokenTracker             = base.GetSupportingTokenTracker(tokenAuthenticator, out specification);
                    if (supportingTokenTracker == null)
                    {
                        throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(System.ServiceModel.SR.GetString("UnknownTokenAuthenticatorUsedInTokenProcessing", new object[] { tokenAuthenticator })));
                    }
                    supportingTokenTracker.RecordToken(token);
                    base.SecurityTokenAuthorizationPoliciesMapping.Add(token, onlys);
                }
            }
            if (token == null)
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("UnableToResolveKeyInfoForVerifyingSignature", new object[] { keyIdentifier, resolver })));
            }
            return(token);
        }
 public void SetElement(ReceiveSecurityHeaderElementCategory elementCategory, object element, ReceiveSecurityHeaderBindingModes bindingMode, string id, bool encrypted, byte[] decryptedBuffer, TokenTracker supportingTokenTracker)
 {
     this.elementCategory        = elementCategory;
     this.element                = element;
     this.bindingMode            = bindingMode;
     this.encrypted              = encrypted;
     this.decryptedBuffer        = decryptedBuffer;
     this.supportingTokenTracker = supportingTokenTracker;
     this.id = id;
 }
 public void SetElement(ReceiveSecurityHeaderElementCategory elementCategory, object element, ReceiveSecurityHeaderBindingModes bindingMode, string id, bool encrypted, byte[] decryptedBuffer, TokenTracker supportingTokenTracker)
 {
     this.elementCategory = elementCategory;
     this.element = element;
     this.bindingMode = bindingMode;
     this.encrypted = encrypted;
     this.decryptedBuffer = decryptedBuffer;
     this.supportingTokenTracker = supportingTokenTracker;
     this.id = id;
 }
예제 #4
0
 public void AppendElement(
     ReceiveSecurityHeaderElementCategory elementCategory, object element,
     ReceiveSecurityHeaderBindingModes bindingMode, string id, TokenTracker supportingTokenTracker)
 {
     if (id != null)
     {
         VerifyIdUniquenessInSecurityHeader(id);
     }
     EnsureCapacityToAdd();
     _elements[Count++].SetElement(elementCategory, element, bindingMode, id, false, null, supportingTokenTracker);
 }
예제 #5
0
        SecurityToken ResolveSignatureToken(SecurityKeyIdentifier keyIdentifier, SecurityTokenResolver resolver, bool isPrimarySignature)
        {
            SecurityToken token;

            TryResolveKeyIdentifier(keyIdentifier, resolver, true, out token);
            if (token == null && !isPrimarySignature)
            {
                // check if there is a rsa key token authenticator
                if (keyIdentifier.Count == 1)
                {
                    RsaKeyIdentifierClause rsaClause;
                    if (keyIdentifier.TryFind <RsaKeyIdentifierClause>(out rsaClause))
                    {
                        RsaSecurityTokenAuthenticator rsaAuthenticator = FindAllowedAuthenticator <RsaSecurityTokenAuthenticator>(false);
                        if (rsaAuthenticator != null)
                        {
                            token = new RsaSecurityToken(rsaClause.Rsa);
                            ReadOnlyCollection <IAuthorizationPolicy> authorizationPolicies = rsaAuthenticator.ValidateToken(token);
                            SupportingTokenAuthenticatorSpecification spec;
                            TokenTracker rsaTracker = GetSupportingTokenTracker(rsaAuthenticator, out spec);
                            if (rsaTracker == null)
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.UnknownTokenAuthenticatorUsedInTokenProcessing, rsaAuthenticator)));
                            }
                            rsaTracker.RecordToken(token);
                            SecurityTokenAuthorizationPoliciesMapping.Add(token, authorizationPolicies);
                        }
                    }
                }
            }
            if (token == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(
                                                                              SR.GetString(SR.UnableToResolveKeyInfoForVerifyingSignature, keyIdentifier, resolver)));
            }
            return(token);
        }
예제 #6
0
 public void AppendToken(SecurityToken token, ReceiveSecurityHeaderBindingModes mode, TokenTracker supportingTokenTracker)
 {
     AppendElement(ReceiveSecurityHeaderElementCategory.Token, token,
                   mode, token.Id, supportingTokenTracker);
 }
예제 #7
0
 public void SetTokenAfterDecryption(int index, SecurityToken token, ReceiveSecurityHeaderBindingModes mode, byte[] decryptedBuffer, TokenTracker supportingTokenTracker)
 {
     SetElementAfterDecryption(index, ReceiveSecurityHeaderElementCategory.Token, token, mode, token.Id, decryptedBuffer, supportingTokenTracker);
 }
예제 #8
0
 public void SetElementAfterDecryption(
     int index,
     ReceiveSecurityHeaderElementCategory elementCategory, object element,
     ReceiveSecurityHeaderBindingModes bindingMode, string id, byte[] decryptedBuffer, TokenTracker supportingTokenTracker)
 {
     Fx.Assert(0 <= index && index < Count, "index out of range");
     Fx.Assert(_elements[index]._elementCategory == ReceiveSecurityHeaderElementCategory.EncryptedData, "Replaced item must be EncryptedData");
     if (id != null)
     {
         VerifyIdUniquenessInSecurityHeader(id);
     }
     _elements[index].PreserveIdBeforeDecryption();
     _elements[index].SetElement(elementCategory, element, bindingMode, id, true, decryptedBuffer, supportingTokenTracker);
 }
        private void ReadToken(XmlDictionaryReader reader, int position, byte[] decryptedBuffer,
                               SecurityToken encryptionToken, string idInEncryptedForm, TimeSpan timeout)
        {
            Fx.Assert((position == AppendPosition) == (decryptedBuffer == null), "inconsistent position, decryptedBuffer parameters");
            Fx.Assert((position == AppendPosition) == (encryptionToken == null), "inconsistent position, encryptionToken parameters");
            string localName    = reader.LocalName;
            string namespaceUri = reader.NamespaceURI;
            string valueType    = reader.GetAttribute(XD.SecurityJan2004Dictionary.ValueType, null);

            SecurityTokenAuthenticator usedTokenAuthenticator;
            SecurityToken token = ReadToken(reader, CombinedUniversalTokenResolver, _allowedAuthenticators, out usedTokenAuthenticator);

            if (token == null)
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.TokenManagerCouldNotReadToken, localName, namespaceUri, valueType)), Message);
            }

            DerivedKeySecurityToken derivedKeyToken = token as DerivedKeySecurityToken;

            if (derivedKeyToken != null)
            {
                EnsureDerivedKeyLimitNotReached();
                derivedKeyToken.InitializeDerivedKey(MaxDerivedKeyLength);
            }

            if (usedTokenAuthenticator == _primaryTokenAuthenticator)
            {
                _allowedAuthenticators.Remove(usedTokenAuthenticator);
            }

            ReceiveSecurityHeaderBindingModes mode;
            TokenTracker supportingTokenTracker = null;

            if (usedTokenAuthenticator == _primaryTokenAuthenticator)
            {
                // this is the primary token. Add to resolver as such
                _universalTokenResolver.Add(token, SecurityTokenReferenceStyle.Internal, _primaryTokenParameters);
                _primaryTokenResolver.Add(token, SecurityTokenReferenceStyle.Internal, _primaryTokenParameters);
                if (_pendingSupportingTokenAuthenticator != null)
                {
                    _allowedAuthenticators.Add(_pendingSupportingTokenAuthenticator);
                    _pendingSupportingTokenAuthenticator = null;
                }

                _primaryTokenTracker.RecordToken(token);
                mode = ReceiveSecurityHeaderBindingModes.Primary;
            }
            else if (usedTokenAuthenticator == DerivedTokenAuthenticator)
            {
                if (token is DerivedKeySecurityTokenStub)
                {
                    if (Layout == SecurityHeaderLayout.Strict)
                    {
                        DerivedKeySecurityTokenStub tmpToken = (DerivedKeySecurityTokenStub)token;
                        throw TraceUtility.ThrowHelperError(new MessageSecurityException(
                                                                SR.Format(SR.UnableToResolveKeyInfoClauseInDerivedKeyToken, tmpToken.TokenToDeriveIdentifier)), Message);
                    }
                }
                else
                {
                    AddDerivedKeyTokenToResolvers(token);
                }

                mode = ReceiveSecurityHeaderBindingModes.Unknown;
            }
            else
            {
                SupportingTokenAuthenticatorSpecification supportingTokenSpec;
                supportingTokenTracker = GetSupportingTokenTracker(usedTokenAuthenticator, out supportingTokenSpec);
                if (supportingTokenTracker == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.Format(SR.UnknownTokenAuthenticatorUsedInTokenProcessing, usedTokenAuthenticator)));
                }

                if (supportingTokenTracker.Token != null)
                {
                    supportingTokenTracker = new TokenTracker(supportingTokenSpec);
                    _supportingTokenTrackers.Add(supportingTokenTracker);
                }

                supportingTokenTracker.RecordToken(token);
                if (encryptionToken != null)
                {
                    supportingTokenTracker.IsEncrypted = true;
                }

                bool isBasic;
                bool isSignedButNotBasic;
                SecurityTokenAttachmentModeHelper.Categorize(supportingTokenSpec.SecurityTokenAttachmentMode, out isBasic, out isSignedButNotBasic, out mode);
                if (isBasic)
                {
                    if (!ExpectBasicTokens)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.BasicTokenNotExpected));
                    }

                    // only basic tokens have to be part of the reference list. Encrypted Saml tokens dont for example
                    if (RequireMessageProtection && encryptionToken != null)
                    {
                        throw ExceptionHelper.PlatformNotSupported();
                    }
                }

                if (isSignedButNotBasic && !ExpectSignedTokens)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.SignedSupportingTokenNotExpected));
                }

                _universalTokenResolver.Add(token, SecurityTokenReferenceStyle.Internal, supportingTokenSpec.TokenParameters);
            }

            if (position == AppendPosition)
            {
                ElementManager.AppendToken(token, mode, supportingTokenTracker);
            }
            else
            {
                ElementManager.SetTokenAfterDecryption(position, token, mode, decryptedBuffer, supportingTokenTracker);
            }
        }
        public void Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
        {
            Fx.Assert(ReaderQuotas != null, "Reader quotas must be set before processing");
            MessageProtectionOrder actualProtectionOrder = _protectionOrder;
            bool wasProtectionOrderDowngraded            = false;

            if (_protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature)
            {
                throw ExceptionHelper.PlatformNotSupported(); // No support for message encryption
            }

            _channelBinding           = channelBinding;
            _extendedProtectionPolicy = extendedProtectionPolicy;
            _orderTracker.SetRequiredProtectionOrder(actualProtectionOrder);

            SetProcessingStarted();
            _timeoutHelper = new TimeoutHelper(timeout);
            Message        = SecurityVerifiedMessage = new SecurityVerifiedMessage(Message, this);
            XmlDictionaryReader reader = CreateSecurityHeaderReader();

            reader.MoveToStartElement();
            if (reader.IsEmptyElement)
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.SecurityHeaderIsEmpty), Message);
            }
            if (RequireMessageProtection)
            {
                _securityElementAttributes = XmlAttributeHolder.ReadAttributes(reader);
            }
            else
            {
                _securityElementAttributes = XmlAttributeHolder.emptyArray;
            }
            reader.ReadStartElement();

            if (_primaryTokenParameters != null)
            {
                _primaryTokenTracker = new TokenTracker(null, _outOfBandPrimaryToken, _allowFirstTokenMismatch);
            }
            // universalTokenResolver is used for resolving tokens
            _universalTokenResolver = new SecurityHeaderTokenResolver(this);
            // primary token resolver is used for resolving primary signature and decryption
            _primaryTokenResolver = new SecurityHeaderTokenResolver(this);
            if (_outOfBandPrimaryToken != null)
            {
                _universalTokenResolver.Add(_outOfBandPrimaryToken, SecurityTokenReferenceStyle.External, _primaryTokenParameters);
                _primaryTokenResolver.Add(_outOfBandPrimaryToken, SecurityTokenReferenceStyle.External, _primaryTokenParameters);
            }
            else if (_outOfBandPrimaryTokenCollection != null)
            {
                for (int i = 0; i < _outOfBandPrimaryTokenCollection.Count; ++i)
                {
                    _universalTokenResolver.Add(_outOfBandPrimaryTokenCollection[i], SecurityTokenReferenceStyle.External, _primaryTokenParameters);
                    _primaryTokenResolver.Add(_outOfBandPrimaryTokenCollection[i], SecurityTokenReferenceStyle.External, _primaryTokenParameters);
                }
            }
            if (_wrappingToken != null)
            {
                _universalTokenResolver.ExpectedWrapper = _wrappingToken;
                _universalTokenResolver.ExpectedWrapperTokenParameters = _wrappingTokenParameters;
                _primaryTokenResolver.ExpectedWrapper = _wrappingToken;
                _primaryTokenResolver.ExpectedWrapperTokenParameters = _wrappingTokenParameters;
            }

            if (_outOfBandTokenResolver == null)
            {
                CombinedUniversalTokenResolver = _universalTokenResolver;
                _combinedPrimaryTokenResolver  = _primaryTokenResolver;
            }
            else
            {
                CombinedUniversalTokenResolver = new AggregateSecurityHeaderTokenResolver(_universalTokenResolver, _outOfBandTokenResolver);
                _combinedPrimaryTokenResolver  = new AggregateSecurityHeaderTokenResolver(_primaryTokenResolver, _outOfBandTokenResolver);
            }

            _allowedAuthenticators = new List <SecurityTokenAuthenticator>();
            if (_primaryTokenAuthenticator != null)
            {
                _allowedAuthenticators.Add(_primaryTokenAuthenticator);
            }
            if (DerivedTokenAuthenticator != null)
            {
                _allowedAuthenticators.Add(DerivedTokenAuthenticator);
            }
            _pendingSupportingTokenAuthenticator = null;
            int numSupportingTokensRequiringDerivation = 0;

            if (_supportingTokenAuthenticators != null && _supportingTokenAuthenticators.Count > 0)
            {
                _supportingTokenTrackers = new List <TokenTracker>(_supportingTokenAuthenticators.Count);
                for (int i = 0; i < _supportingTokenAuthenticators.Count; ++i)
                {
                    SupportingTokenAuthenticatorSpecification spec = _supportingTokenAuthenticators[i];
                    switch (spec.SecurityTokenAttachmentMode)
                    {
                    case SecurityTokenAttachmentMode.Endorsing:
                        _hasEndorsingOrSignedEndorsingSupportingTokens = true;
                        break;

                    case SecurityTokenAttachmentMode.Signed:
                        break;

                    case SecurityTokenAttachmentMode.SignedEndorsing:
                        _hasEndorsingOrSignedEndorsingSupportingTokens = true;
                        break;

                    case SecurityTokenAttachmentMode.SignedEncrypted:
                        break;
                    }

                    if ((_primaryTokenAuthenticator != null) && (_primaryTokenAuthenticator.GetType().Equals(spec.TokenAuthenticator.GetType())))
                    {
                        _pendingSupportingTokenAuthenticator = spec.TokenAuthenticator;
                    }
                    else
                    {
                        _allowedAuthenticators.Add(spec.TokenAuthenticator);
                    }
                    if (spec.TokenParameters.RequireDerivedKeys && !spec.TokenParameters.HasAsymmetricKey &&
                        (spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endorsing || spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.SignedEndorsing))
                    {
                        ++numSupportingTokensRequiringDerivation;
                    }
                    _supportingTokenTrackers.Add(new TokenTracker(spec));
                }
            }

            if (DerivedTokenAuthenticator != null)
            {
                // we expect key derivation. Compute quotas for derived keys
                int maxKeyDerivationLengthInBits = AlgorithmSuite.DefaultEncryptionKeyDerivationLength >= AlgorithmSuite.DefaultSignatureKeyDerivationLength ?
                                                   AlgorithmSuite.DefaultEncryptionKeyDerivationLength : AlgorithmSuite.DefaultSignatureKeyDerivationLength;
                MaxDerivedKeyLength = maxKeyDerivationLengthInBits / 8;
                // the upper bound of derived keys is (1 for primary signature + 1 for encryption + supporting token signatures requiring derivation)*2
                // the multiplication by 2 is to take care of interop scenarios that may arise that require more derived keys than the lower bound.
                _maxDerivedKeys = (1 + 1 + numSupportingTokensRequiringDerivation) * 2;
            }

            SecurityHeaderElementInferenceEngine engine = SecurityHeaderElementInferenceEngine.GetInferenceEngine(Layout);

            engine.ExecuteProcessingPasses(this, reader);
            if (RequireMessageProtection)
            {
                throw ExceptionHelper.PlatformNotSupported();
            }

            EnsureDecryptionComplete();

            _signatureTracker.SetDerivationSourceIfRequired();
            _encryptionTracker.SetDerivationSourceIfRequired();
            if (EncryptionToken != null)
            {
                throw ExceptionHelper.PlatformNotSupported();
            }

            // ensure that the primary signature was signed with derived keys if required
            if (EnforceDerivedKeyRequirement)
            {
                if (SignatureToken != null)
                {
                    if (_primaryTokenParameters != null)
                    {
                        if (_primaryTokenParameters.RequireDerivedKeys && !_primaryTokenParameters.HasAsymmetricKey && !_primaryTokenTracker.IsDerivedFrom)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.Format(SR.PrimarySignatureWasNotSignedByDerivedKey, _primaryTokenParameters)));
                        }
                    }
                    else if (_wrappingTokenParameters != null && _wrappingTokenParameters.RequireDerivedKeys)
                    {
                        if (!_signatureTracker.IsDerivedToken)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.Format(SR.PrimarySignatureWasNotSignedByDerivedWrappedKey, _wrappingTokenParameters)));
                        }
                    }
                }

                // verify that the encryption is using key derivation
                if (EncryptionToken != null)
                {
                    throw ExceptionHelper.PlatformNotSupported();
                }
            }

            if (wasProtectionOrderDowngraded && (BasicSupportingTokens != null) && (BasicSupportingTokens.Count > 0))
            {
                throw ExceptionHelper.PlatformNotSupported();
            }

            // verify all supporting token parameters have their requirements met
            if (_supportingTokenTrackers != null && _supportingTokenTrackers.Count > 0)
            {
                throw ExceptionHelper.PlatformNotSupported();
            }

            if (_replayDetectionEnabled)
            {
                throw ExceptionHelper.PlatformNotSupported();
            }

            if (ExpectSignatureConfirmation)
            {
                throw ExceptionHelper.PlatformNotSupported();
            }

            MarkHeaderAsUnderstood();
        }
예제 #11
0
 public void SetElementAfterDecryption(int index, ReceiveSecurityHeaderElementCategory elementCategory, object element, ReceiveSecurityHeaderBindingModes bindingMode, string id, byte[] decryptedBuffer, TokenTracker supportingTokenTracker)
 {
     if (id != null)
     {
         this.VerifyIdUniquenessInSecurityHeader(id);
     }
     this.elements[index].PreserveIdBeforeDecryption();
     this.elements[index].SetElement(elementCategory, element, bindingMode, id, true, decryptedBuffer, supportingTokenTracker);
 }