| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Collections.Generic; |
| | | 6 | | using System.Collections.ObjectModel; |
| | | 7 | | using System.Threading.Tasks; |
| | | 8 | | using System.Xml; |
| | | 9 | | using CoreWCF.Channels; |
| | | 10 | | using CoreWCF.Description; |
| | | 11 | | using CoreWCF.IdentityModel.Selectors; |
| | | 12 | | using CoreWCF.IdentityModel.Tokens; |
| | | 13 | | using CoreWCF.Runtime; |
| | | 14 | | using CoreWCF.Security.Tokens; |
| | | 15 | | |
| | | 16 | | namespace CoreWCF.Security |
| | | 17 | | { |
| | | 18 | | internal sealed class AcceptorSessionSymmetricTransportSecurityProtocol : TransportSecurityProtocol, IAcceptorSecuri |
| | | 19 | | { |
| | | 20 | | private SecurityToken _outgoingSessionToken; |
| | | 21 | | private SecurityTokenAuthenticator _sessionTokenAuthenticator; |
| | | 22 | | private SecurityTokenResolver _sessionTokenResolver; |
| | | 23 | | private ReadOnlyCollection<SecurityTokenResolver> _sessionTokenResolverList; |
| | | 24 | | private UniqueId _sessionId; |
| | | 25 | | private Collection<SupportingTokenAuthenticatorSpecification> _sessionTokenAuthenticatorSpecificationList; |
| | | 26 | | private readonly bool _requireDerivedKeys; |
| | | 27 | | |
| | 10 | 28 | | public AcceptorSessionSymmetricTransportSecurityProtocol(SessionSymmetricTransportSecurityProtocolFactory factor |
| | | 29 | | { |
| | 10 | 30 | | if (factory.ActAsInitiator == true) |
| | | 31 | | { |
| | | 32 | | Fx.Assert("This protocol can only be used at the recipient."); |
| | 0 | 33 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Pro |
| | | 34 | | } |
| | 10 | 35 | | _requireDerivedKeys = factory.SecurityTokenParameters.RequireDerivedKeys; |
| | 10 | 36 | | } |
| | | 37 | | |
| | | 38 | | private SessionSymmetricTransportSecurityProtocolFactory Factory |
| | | 39 | | { |
| | 210 | 40 | | get { return (SessionSymmetricTransportSecurityProtocolFactory)SecurityProtocolFactory; } |
| | | 41 | | } |
| | | 42 | | |
| | | 43 | | public bool ReturnCorrelationState |
| | | 44 | | { |
| | | 45 | | get |
| | | 46 | | { |
| | 0 | 47 | | return false; |
| | | 48 | | } |
| | | 49 | | set |
| | | 50 | | { |
| | 8 | 51 | | } |
| | | 52 | | } |
| | | 53 | | |
| | | 54 | | public void SetSessionTokenAuthenticator(UniqueId sessionId, SecurityTokenAuthenticator sessionTokenAuthenticato |
| | | 55 | | { |
| | 10 | 56 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 10 | 57 | | _sessionId = sessionId; |
| | 10 | 58 | | _sessionTokenResolver = sessionTokenResolver; |
| | 10 | 59 | | Collection<SecurityTokenResolver> tmp = new Collection<SecurityTokenResolver> |
| | 10 | 60 | | { |
| | 10 | 61 | | _sessionTokenResolver |
| | 10 | 62 | | }; |
| | 10 | 63 | | _sessionTokenResolverList = new ReadOnlyCollection<SecurityTokenResolver>(tmp); |
| | 10 | 64 | | _sessionTokenAuthenticator = sessionTokenAuthenticator; |
| | 10 | 65 | | SupportingTokenAuthenticatorSpecification spec = new SupportingTokenAuthenticatorSpecification(_sessionToken |
| | 10 | 66 | | _sessionTokenAuthenticatorSpecificationList = new Collection<SupportingTokenAuthenticatorSpecification> |
| | 10 | 67 | | { |
| | 10 | 68 | | spec |
| | 10 | 69 | | }; |
| | 10 | 70 | | } |
| | | 71 | | |
| | | 72 | | public SecurityToken GetOutgoingSessionToken() |
| | | 73 | | { |
| | 0 | 74 | | return _outgoingSessionToken; |
| | | 75 | | } |
| | | 76 | | |
| | | 77 | | public void SetOutgoingSessionToken(SecurityToken token) |
| | | 78 | | { |
| | 10 | 79 | | _outgoingSessionToken = token ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(tok |
| | 10 | 80 | | } |
| | | 81 | | |
| | | 82 | | protected override async ValueTask<Message> VerifyIncomingMessageCoreAsync(Message message, TimeSpan timeout) |
| | | 83 | | { |
| | 20 | 84 | | string actor = string.Empty; // message.Version.Envelope.UltimateDestinationActor; |
| | 20 | 85 | | ReceiveSecurityHeader securityHeader = Factory.StandardsManager.TryCreateReceiveSecurityHeader(message, acto |
| | 20 | 86 | | Factory.IncomingAlgorithmSuite, MessageDirection.Input); |
| | 20 | 87 | | securityHeader.RequireMessageProtection = false; |
| | 20 | 88 | | securityHeader.ReaderQuotas = Factory.SecurityBindingElement.ReaderQuotas; |
| | 20 | 89 | | IList<SupportingTokenAuthenticatorSpecification> supportingAuthenticators = GetSupportingTokenAuthenticators |
| | 20 | 90 | | ReadOnlyCollection<SecurityTokenResolver> mergedTokenResolvers = MergeOutOfBandResolvers(supportingAuthentic |
| | 20 | 91 | | if (supportingAuthenticators != null && supportingAuthenticators.Count > 0) |
| | | 92 | | { |
| | 0 | 93 | | supportingAuthenticators = new List<SupportingTokenAuthenticatorSpecification>(supportingAuthenticators) |
| | 0 | 94 | | supportingAuthenticators.Insert(0, _sessionTokenAuthenticatorSpecificationList[0]); |
| | | 95 | | } |
| | | 96 | | else |
| | | 97 | | { |
| | 20 | 98 | | supportingAuthenticators = _sessionTokenAuthenticatorSpecificationList; |
| | | 99 | | } |
| | 20 | 100 | | securityHeader.ConfigureTransportBindingServerReceiveHeader(supportingAuthenticators); |
| | 20 | 101 | | securityHeader.ConfigureOutOfBandTokenResolver(mergedTokenResolvers); |
| | 20 | 102 | | securityHeader.ExpectEndorsingTokens = true; |
| | 20 | 103 | | TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); |
| | | 104 | | |
| | 20 | 105 | | securityHeader.ReplayDetectionEnabled = Factory.DetectReplays; |
| | 20 | 106 | | securityHeader.SetTimeParameters(Factory.NonceCache, Factory.ReplayWindow, Factory.MaxClockSkew); |
| | | 107 | | // do not enforce key derivation requirement for Cancel messages due to WSE interop |
| | 20 | 108 | | securityHeader.EnforceDerivedKeyRequirement = (message.Headers.Action != Factory.StandardsManager.SecureConv |
| | 20 | 109 | | await securityHeader.ProcessAsync(timeoutHelper.RemainingTime(), SecurityUtils.GetChannelBindingFromMessage( |
| | 20 | 110 | | if (securityHeader.Timestamp == null) |
| | | 111 | | { |
| | 0 | 112 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.Format(SR.Re |
| | | 113 | | } |
| | 20 | 114 | | bool didSessionSctEndorse = false; |
| | 20 | 115 | | if (securityHeader.EndorsingSupportingTokens != null) |
| | | 116 | | { |
| | 40 | 117 | | for (int i = 0; i < securityHeader.EndorsingSupportingTokens.Count; ++i) |
| | | 118 | | { |
| | 20 | 119 | | SecurityContextSecurityToken signingSct = (securityHeader.EndorsingSupportingTokens[i] as SecurityCo |
| | 20 | 120 | | if (signingSct != null && signingSct.ContextId == _sessionId) |
| | | 121 | | { |
| | 20 | 122 | | didSessionSctEndorse = true; |
| | 20 | 123 | | break; |
| | | 124 | | } |
| | | 125 | | } |
| | | 126 | | } |
| | 20 | 127 | | if (!didSessionSctEndorse) |
| | | 128 | | { |
| | 0 | 129 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.Format(SR.No |
| | | 130 | | } |
| | 20 | 131 | | Message processedMessage = securityHeader.ProcessedMessage; |
| | 20 | 132 | | AttachRecipientSecurityProperty(processedMessage, securityHeader.BasicSupportingTokens, securityHeader.Endor |
| | 20 | 133 | | securityHeader.SignedEndorsingSupportingTokens, securityHeader.SignedSupportingTokens, securityHeader.Se |
| | 20 | 134 | | OnIncomingMessageVerified(processedMessage); |
| | 20 | 135 | | return processedMessage; |
| | 20 | 136 | | } |
| | | 137 | | } |
| | | 138 | | } |