Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,355 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IdentityModel.Policy;
using System.IdentityModel.Tokens;
using System.Runtime;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Diagnostics;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Security.Tokens;
using System.Xml;
sealed class AcceleratedTokenAuthenticator : NegotiationTokenAuthenticator<NegotiationTokenAuthenticatorState>
{
SecurityBindingElement bootstrapSecurityBindingElement;
SecurityKeyEntropyMode keyEntropyMode;
bool shouldMatchRstWithEndpointFilter;
bool preserveBootstrapTokens;
public AcceleratedTokenAuthenticator()
: base()
{
keyEntropyMode = AcceleratedTokenProvider.defaultKeyEntropyMode;
}
public bool PreserveBootstrapTokens
{
get
{
return this.preserveBootstrapTokens;
}
set
{
this.preserveBootstrapTokens = value;
}
}
public override XmlDictionaryString RequestSecurityTokenAction
{
get
{
return this.StandardsManager.SecureConversationDriver.IssueAction;
}
}
public override XmlDictionaryString RequestSecurityTokenResponseAction
{
get
{
return this.StandardsManager.SecureConversationDriver.IssueResponseAction;
}
}
public override XmlDictionaryString RequestSecurityTokenResponseFinalAction
{
get
{
return this.StandardsManager.SecureConversationDriver.IssueResponseAction;
}
}
public SecurityBindingElement BootstrapSecurityBindingElement
{
get { return this.bootstrapSecurityBindingElement; }
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
if (value == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
}
this.bootstrapSecurityBindingElement = (SecurityBindingElement)value.Clone();
}
}
public SecurityKeyEntropyMode KeyEntropyMode
{
get
{
return this.keyEntropyMode;
}
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
SecurityKeyEntropyModeHelper.Validate(value);
this.keyEntropyMode = value;
}
}
protected override bool IsMultiLegNegotiation
{
get
{
return false;
}
}
protected override MessageFilter GetListenerFilter()
{
return new RstDirectFilter(this.StandardsManager, this);
}
protected override Binding GetNegotiationBinding(Binding binding)
{
CustomBinding customBinding = new CustomBinding(binding);
customBinding.Elements.Insert(0, new AcceleratedTokenAuthenticatorBindingElement(this));
return customBinding;
}
internal IChannelListener<TChannel> BuildNegotiationChannelListener<TChannel>(BindingContext context)
where TChannel : class, IChannel
{
SecurityCredentialsManager securityCredentials = this.IssuerBindingContext.BindingParameters.Find<SecurityCredentialsManager>();
if (securityCredentials == null)
{
securityCredentials = ServiceCredentials.CreateDefaultCredentials();
}
this.bootstrapSecurityBindingElement.ReaderQuotas = context.GetInnerProperty<XmlDictionaryReaderQuotas>();
if (this.bootstrapSecurityBindingElement.ReaderQuotas == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas)));
}
TransportBindingElement transportBindingElement = context.RemainingBindingElements.Find<TransportBindingElement>();
if (transportBindingElement != null)
this.bootstrapSecurityBindingElement.MaxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize;
SecurityProtocolFactory securityProtocolFactory = this.bootstrapSecurityBindingElement.CreateSecurityProtocolFactory<TChannel>(this.IssuerBindingContext.Clone(), securityCredentials, true, this.IssuerBindingContext.Clone());
MessageSecurityProtocolFactory soapBindingFactory = securityProtocolFactory as MessageSecurityProtocolFactory;
if (soapBindingFactory != null)
{
soapBindingFactory.ApplyConfidentiality = soapBindingFactory.ApplyIntegrity
= soapBindingFactory.RequireConfidentiality = soapBindingFactory.RequireIntegrity = true;
MessagePartSpecification bodyPart = new MessagePartSpecification(true);
soapBindingFactory.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, RequestSecurityTokenResponseAction);
soapBindingFactory.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, RequestSecurityTokenResponseAction);
soapBindingFactory.ProtectionRequirements.IncomingSignatureParts.AddParts(bodyPart, RequestSecurityTokenAction);
soapBindingFactory.ProtectionRequirements.IncomingEncryptionParts.AddParts(bodyPart, RequestSecurityTokenAction);
}
SecurityChannelListener<TChannel> securityChannelListener =
new SecurityChannelListener<TChannel>(this.bootstrapSecurityBindingElement, context);
securityChannelListener.SecurityProtocolFactory = securityProtocolFactory;
// do not send back unsecured faults over composite duplex
securityChannelListener.SendUnsecuredFaults = !SecurityUtils.IsCompositeDuplexBinding(context);
ChannelBuilder channelBuilder = new ChannelBuilder(context, true);
securityChannelListener.InitializeListener(channelBuilder);
this.shouldMatchRstWithEndpointFilter = SecurityUtils.ShouldMatchRstWithEndpointFilter(this.bootstrapSecurityBindingElement);
return securityChannelListener;
}
protected override BodyWriter ProcessRequestSecurityToken(Message request, RequestSecurityToken requestSecurityToken, out NegotiationTokenAuthenticatorState negotiationState)
{
if (request == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("request");
}
if (requestSecurityToken == null)
{
throw TraceUtility.ThrowHelperArgumentNull("requestSecurityToken", request);
}
try
{
if (requestSecurityToken.RequestType != null && requestSecurityToken.RequestType != this.StandardsManager.TrustDriver.RequestTypeIssue)
{
throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.InvalidRstRequestType, requestSecurityToken.RequestType)), request);
}
if (requestSecurityToken.TokenType != null && requestSecurityToken.TokenType != this.SecurityContextTokenUri)
{
throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.CannotIssueRstTokenType, requestSecurityToken.TokenType)), request);
}
EndpointAddress appliesTo;
DataContractSerializer appliesToSerializer;
string appliesToName;
string appliesToNamespace;
requestSecurityToken.GetAppliesToQName(out appliesToName, out appliesToNamespace);
if (appliesToName == AddressingStrings.EndpointReference && appliesToNamespace == request.Version.Addressing.Namespace)
{
if (request.Version.Addressing == AddressingVersion.WSAddressing10)
{
appliesToSerializer = DataContractSerializerDefaults.CreateSerializer(typeof(EndpointAddress10), DataContractSerializerDefaults.MaxItemsInObjectGraph);
appliesTo = requestSecurityToken.GetAppliesTo<EndpointAddress10>(appliesToSerializer).ToEndpointAddress();
}
else if (request.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
{
appliesToSerializer = DataContractSerializerDefaults.CreateSerializer(typeof(EndpointAddressAugust2004), DataContractSerializerDefaults.MaxItemsInObjectGraph);
appliesTo = requestSecurityToken.GetAppliesTo<EndpointAddressAugust2004>(appliesToSerializer).ToEndpointAddress();
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, request.Version.Addressing)));
}
}
else
{
appliesTo = null;
appliesToSerializer = null;
}
if (this.shouldMatchRstWithEndpointFilter)
{
SecurityUtils.MatchRstWithEndpointFilter(request, this.EndpointFilterTable, this.ListenUri);
}
int issuedKeySize;
byte[] issuerEntropy;
byte[] proofKey;
SecurityToken proofToken;
WSTrust.Driver.ProcessRstAndIssueKey(requestSecurityToken, null, this.KeyEntropyMode, this.SecurityAlgorithmSuite,
out issuedKeySize, out issuerEntropy, out proofKey, out proofToken);
UniqueId contextId = SecurityUtils.GenerateUniqueId();
string id = SecurityUtils.GenerateId();
DateTime effectiveTime = DateTime.UtcNow;
DateTime expirationTime = TimeoutHelper.Add(effectiveTime, this.ServiceTokenLifetime);
// ensure that a SecurityContext is present in the message
SecurityMessageProperty securityProperty = request.Properties.Security;
ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies;
if (securityProperty != null)
authorizationPolicies = SecuritySessionSecurityTokenAuthenticator.CreateSecureConversationPolicies(securityProperty, expirationTime);
else
authorizationPolicies = EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
SecurityContextSecurityToken serviceToken = this.IssueSecurityContextToken(contextId, id, proofKey, effectiveTime, expirationTime, authorizationPolicies,
this.EncryptStateInServiceToken);
if (this.preserveBootstrapTokens)
{
serviceToken.BootstrapMessageProperty = (securityProperty == null) ? null : (SecurityMessageProperty)securityProperty.CreateCopy();
SecurityUtils.ErasePasswordInUsernameTokenIfPresent(serviceToken.BootstrapMessageProperty);
}
RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(this.StandardsManager);
rstr.Context = requestSecurityToken.Context;
rstr.KeySize = issuedKeySize;
rstr.RequestedUnattachedReference = this.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(serviceToken, SecurityTokenReferenceStyle.External);
rstr.RequestedAttachedReference = this.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(serviceToken, SecurityTokenReferenceStyle.Internal);
rstr.TokenType = this.SecurityContextTokenUri;
rstr.RequestedSecurityToken = serviceToken;
if (issuerEntropy != null)
{
rstr.SetIssuerEntropy(issuerEntropy);
rstr.ComputeKey = true;
}
if (proofToken != null)
{
rstr.RequestedProofToken = proofToken;
}
if (appliesTo != null)
{
if (request.Version.Addressing == AddressingVersion.WSAddressing10)
{
rstr.SetAppliesTo<EndpointAddress10>(EndpointAddress10.FromEndpointAddress(appliesTo), appliesToSerializer);
}
else if (request.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
{
rstr.SetAppliesTo<EndpointAddressAugust2004>(EndpointAddressAugust2004.FromEndpointAddress(appliesTo), appliesToSerializer);
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, request.Version.Addressing)));
}
}
rstr.MakeReadOnly();
negotiationState = new NegotiationTokenAuthenticatorState();
negotiationState.SetServiceToken(serviceToken);
if (this.StandardsManager.MessageSecurityVersion.SecureConversationVersion == SecureConversationVersion.WSSecureConversationFeb2005)
return rstr;
else if (this.StandardsManager.MessageSecurityVersion.SecureConversationVersion == SecureConversationVersion.WSSecureConversation13)
{
List<RequestSecurityTokenResponse> rstrList = new List<RequestSecurityTokenResponse>(1);
rstrList.Add(rstr);
RequestSecurityTokenResponseCollection rstrCollection = new RequestSecurityTokenResponseCollection(rstrList, this.StandardsManager);
return rstrCollection;
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
}
}
finally
{
SecuritySessionSecurityTokenAuthenticator.RemoveCachedTokensIfRequired(request.Properties.Security);
}
}
protected override BodyWriter ProcessRequestSecurityTokenResponse(NegotiationTokenAuthenticatorState negotiationState, Message request, RequestSecurityTokenResponse requestSecurityTokenResponse)
{
throw TraceUtility.ThrowHelperWarning(new NotSupportedException(SR.GetString(SR.RstDirectDoesNotExpectRstr)), request);
}
class RstDirectFilter : HeaderFilter
{
SecurityStandardsManager standardsManager;
AcceleratedTokenAuthenticator authenticator;
public RstDirectFilter(SecurityStandardsManager standardsManager, AcceleratedTokenAuthenticator authenticator)
{
this.standardsManager = standardsManager;
this.authenticator = authenticator;
}
public override bool Match(Message message)
{
if (message.Headers.Action == this.authenticator.RequestSecurityTokenAction.Value)
{
return this.standardsManager.DoesMessageContainSecurityHeader(message);
}
else
{
return false;
}
}
}
}
class AcceleratedTokenAuthenticatorBindingElement : BindingElement
{
AcceleratedTokenAuthenticator authenticator;
public AcceleratedTokenAuthenticatorBindingElement(AcceleratedTokenAuthenticator authenticator)
{
this.authenticator = authenticator;
}
public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
if (context == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
return authenticator.BuildNegotiationChannelListener<TChannel>(context);
}
public override BindingElement Clone()
{
return new AcceleratedTokenAuthenticatorBindingElement(this.authenticator);
}
public override T GetProperty<T>(BindingContext context)
{
if (typeof(T) == typeof(ISecurityCapabilities))
{
return (T)(object)authenticator.BootstrapSecurityBindingElement.GetProperty<ISecurityCapabilities>(context);
}
return context.GetInnerProperty<T>();
}
}
}

View File

@@ -0,0 +1,322 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Collections.ObjectModel;
using System.IdentityModel.Policy;
using System.IdentityModel.Tokens;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Diagnostics;
using System.Xml;
using SafeFreeCredentials = System.IdentityModel.SafeFreeCredentials;
class AcceleratedTokenProvider :
NegotiationTokenProvider<AcceleratedTokenProviderState>
{
internal const SecurityKeyEntropyMode defaultKeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
SecurityKeyEntropyMode keyEntropyMode = defaultKeyEntropyMode;
SecurityBindingElement bootstrapSecurityBindingElement;
Uri privacyNoticeUri;
int privacyNoticeVersion;
ChannelParameterCollection channelParameters;
SafeFreeCredentials credentialsHandle;
bool ownCredentialsHandle;
public AcceleratedTokenProvider(SafeFreeCredentials credentialsHandle)
: base()
{
this.credentialsHandle = credentialsHandle;
}
public SecurityKeyEntropyMode KeyEntropyMode
{
get
{
return this.keyEntropyMode;
}
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
SecurityKeyEntropyModeHelper.Validate(value);
this.keyEntropyMode = value;
}
}
public SecurityBindingElement BootstrapSecurityBindingElement
{
get { return this.bootstrapSecurityBindingElement; }
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
if (value == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
}
this.bootstrapSecurityBindingElement = (SecurityBindingElement) value.Clone();
}
}
public Uri PrivacyNoticeUri
{
get { return this.privacyNoticeUri; }
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
this.privacyNoticeUri = value;
}
}
public int PrivacyNoticeVersion
{
get { return this.privacyNoticeVersion; }
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
this.privacyNoticeVersion = value;
}
}
public ChannelParameterCollection ChannelParameters
{
get { return this.channelParameters; }
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
this.channelParameters = value;
}
}
// SC/Trust workshop change to turn off context
protected override bool IsMultiLegNegotiation
{
get { return false; }
}
public override XmlDictionaryString RequestSecurityTokenAction
{
get
{
return this.StandardsManager.SecureConversationDriver.IssueAction;
}
}
public override XmlDictionaryString RequestSecurityTokenResponseAction
{
get
{
return this.StandardsManager.SecureConversationDriver.IssueResponseAction;
}
}
public override void OnOpen(TimeSpan timeout)
{
if (this.BootstrapSecurityBindingElement == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BootstrapSecurityBindingElementNotSet, this.GetType())));
}
base.OnOpen(timeout);
}
public override void OnOpening()
{
base.OnOpening();
if (this.credentialsHandle == null)
{
if (this.BootstrapSecurityBindingElement == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BootstrapSecurityBindingElementNotSet, this.GetType())));
}
this.credentialsHandle = SecurityUtils.GetCredentialsHandle(this.BootstrapSecurityBindingElement, this.IssuerBindingContext);
this.ownCredentialsHandle = true;
}
}
public override void OnClose(TimeSpan timeout)
{
base.OnClose(timeout);
FreeCredentialsHandle();
}
public override void OnAbort()
{
base.OnAbort();
FreeCredentialsHandle();
}
void FreeCredentialsHandle()
{
if (this.credentialsHandle != null)
{
if (this.ownCredentialsHandle)
{
this.credentialsHandle.Close();
}
this.credentialsHandle = null;
}
}
protected override IChannelFactory<IRequestChannel> GetNegotiationChannelFactory(IChannelFactory<IRequestChannel> transportChannelFactory, ChannelBuilder channelBuilder)
{
ISecurityCapabilities securityCapabilities = this.bootstrapSecurityBindingElement.GetProperty<ISecurityCapabilities>(this.IssuerBindingContext);
SecurityCredentialsManager securityCredentials = this.IssuerBindingContext.BindingParameters.Find<SecurityCredentialsManager>();
if (securityCredentials == null)
{
securityCredentials = ClientCredentials.CreateDefaultCredentials();
}
this.bootstrapSecurityBindingElement.ReaderQuotas = this.IssuerBindingContext.GetInnerProperty<XmlDictionaryReaderQuotas>();
if (this.bootstrapSecurityBindingElement.ReaderQuotas == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas)));
}
TransportBindingElement transportBindingElement = this.IssuerBindingContext.RemainingBindingElements.Find<TransportBindingElement>();
if (transportBindingElement != null)
this.bootstrapSecurityBindingElement.MaxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize;
SecurityProtocolFactory securityProtocolFactory = this.bootstrapSecurityBindingElement.CreateSecurityProtocolFactory<IRequestChannel>(this.IssuerBindingContext.Clone(), securityCredentials, false, this.IssuerBindingContext.Clone());
MessageSecurityProtocolFactory soapBindingFactory = (securityProtocolFactory as MessageSecurityProtocolFactory);
if (soapBindingFactory != null)
{
soapBindingFactory.ApplyConfidentiality = soapBindingFactory.ApplyIntegrity
= soapBindingFactory.RequireConfidentiality = soapBindingFactory.RequireIntegrity = true;
MessagePartSpecification bodyPart = new MessagePartSpecification(true);
soapBindingFactory.ProtectionRequirements.IncomingSignatureParts.AddParts(bodyPart, RequestSecurityTokenAction);
soapBindingFactory.ProtectionRequirements.IncomingEncryptionParts.AddParts(bodyPart, RequestSecurityTokenAction);
soapBindingFactory.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, RequestSecurityTokenResponseAction);
soapBindingFactory.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, RequestSecurityTokenResponseAction);
}
securityProtocolFactory.PrivacyNoticeUri = this.PrivacyNoticeUri;
securityProtocolFactory.PrivacyNoticeVersion = this.PrivacyNoticeVersion;
return new SecurityChannelFactory<IRequestChannel>(
securityCapabilities, this.IssuerBindingContext, channelBuilder, securityProtocolFactory, transportChannelFactory);
}
protected override IRequestChannel CreateClientChannel(EndpointAddress target, Uri via)
{
IRequestChannel result = base.CreateClientChannel(target, via);
if (this.channelParameters != null)
{
this.channelParameters.PropagateChannelParameters(result);
}
if (this.ownCredentialsHandle)
{
ChannelParameterCollection newParameters = result.GetProperty<ChannelParameterCollection>();
if (newParameters != null)
{
newParameters.Add(new SspiIssuanceChannelParameter(true, this.credentialsHandle));
}
}
return result;
}
protected override bool CreateNegotiationStateCompletesSynchronously(EndpointAddress target, Uri via)
{
return true;
}
protected override AcceleratedTokenProviderState CreateNegotiationState(EndpointAddress target, Uri via, TimeSpan timeout)
{
byte[] keyEntropy;
if (this.keyEntropyMode == SecurityKeyEntropyMode.ClientEntropy || this.keyEntropyMode == SecurityKeyEntropyMode.CombinedEntropy)
{
keyEntropy = new byte[this.SecurityAlgorithmSuite.DefaultSymmetricKeyLength / 8];
CryptoHelper.FillRandomBytes(keyEntropy);
}
else
{
keyEntropy = null;
}
return new AcceleratedTokenProviderState(keyEntropy);
}
protected override IAsyncResult BeginCreateNegotiationState(EndpointAddress target, Uri via, TimeSpan timeout, AsyncCallback callback, object state)
{
return new CompletedAsyncResult<AcceleratedTokenProviderState>(CreateNegotiationState(target, via, timeout), callback, state);
}
protected override AcceleratedTokenProviderState EndCreateNegotiationState(IAsyncResult result)
{
return CompletedAsyncResult<AcceleratedTokenProviderState>.End(result);
}
protected override BodyWriter GetFirstOutgoingMessageBody(AcceleratedTokenProviderState negotiationState, out MessageProperties messageProperties)
{
messageProperties = null;
RequestSecurityToken rst = new RequestSecurityToken(this.StandardsManager);
rst.Context = negotiationState.Context;
rst.KeySize = this.SecurityAlgorithmSuite.DefaultSymmetricKeyLength;
rst.TokenType = this.SecurityContextTokenUri;
byte[] requestorEntropy = negotiationState.GetRequestorEntropy();
if (requestorEntropy != null)
{
rst.SetRequestorEntropy(requestorEntropy);
}
rst.MakeReadOnly();
return rst;
}
protected override BodyWriter GetNextOutgoingMessageBody(Message incomingMessage, AcceleratedTokenProviderState negotiationState)
{
ThrowIfFault(incomingMessage, this.TargetAddress);
if (incomingMessage.Headers.Action != RequestSecurityTokenResponseAction.Value)
{
throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.InvalidActionForNegotiationMessage, incomingMessage.Headers.Action)), incomingMessage);
}
// get the claims corresponding to the server
SecurityMessageProperty serverContextProperty = incomingMessage.Properties.Security;
ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies;
if (serverContextProperty != null && serverContextProperty.ServiceSecurityContext != null)
{
authorizationPolicies = serverContextProperty.ServiceSecurityContext.AuthorizationPolicies;
}
else
{
authorizationPolicies = EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
}
RequestSecurityTokenResponse rstr = null;
XmlDictionaryReader bodyReader = incomingMessage.GetReaderAtBodyContents();
using (bodyReader)
{
if (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005)
rstr = RequestSecurityTokenResponse.CreateFrom(this.StandardsManager, bodyReader);
else if (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13)
{
RequestSecurityTokenResponseCollection rstrc = this.StandardsManager.TrustDriver.CreateRequestSecurityTokenResponseCollection(bodyReader);
foreach (RequestSecurityTokenResponse rstrItem in rstrc.RstrCollection)
{
if (rstr != null)
{
// More than one RSTR is found. So throw an exception.
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MoreThanOneRSTRInRSTRC)));
}
rstr = rstrItem;
}
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
}
incomingMessage.ReadFromBodyContentsToEnd(bodyReader);
}
if (rstr.Context != negotiationState.Context)
{
throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.BadSecurityNegotiationContext)), incomingMessage);
}
byte[] keyEntropy = negotiationState.GetRequestorEntropy();
GenericXmlSecurityToken serviceToken = rstr.GetIssuedToken(null, null, this.keyEntropyMode, keyEntropy, this.SecurityContextTokenUri, authorizationPolicies, this.SecurityAlgorithmSuite.DefaultSymmetricKeyLength, false);
negotiationState.SetServiceToken(serviceToken);
return null;
}
}
}

View File

@@ -0,0 +1,20 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Security
{
class AcceleratedTokenProviderState : IssuanceTokenProviderState
{
byte[] entropy;
public AcceleratedTokenProviderState(byte[] value)
{
this.entropy = value;
}
public byte[] GetRequestorEntropy()
{
return this.entropy;
}
}
}

View File

@@ -0,0 +1,205 @@
//----------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Security.Tokens;
using System.Xml;
sealed class AcceptorSessionSymmetricMessageSecurityProtocol : MessageSecurityProtocol, IAcceptorSecuritySessionProtocol
{
SecurityToken outgoingSessionToken;
SecurityTokenAuthenticator sessionTokenAuthenticator;
SecurityTokenResolver sessionTokenResolver;
ReadOnlyCollection<SecurityTokenResolver> sessionResolverList;
bool returnCorrelationState = false;
DerivedKeySecurityToken derivedSignatureToken;
DerivedKeySecurityToken derivedEncryptionToken;
UniqueId sessionId;
SecurityStandardsManager sessionStandardsManager;
Object thisLock = new Object();
bool requireDerivedKeys;
public AcceptorSessionSymmetricMessageSecurityProtocol(SessionSymmetricMessageSecurityProtocolFactory factory,
EndpointAddress target)
: base(factory, target, null)
{
if (factory.ActAsInitiator == true)
{
Fx.Assert("This protocol can only be used at the recipient.");
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ProtocolMustBeRecipient, this.GetType().ToString())));
}
this.requireDerivedKeys = factory.SecurityTokenParameters.RequireDerivedKeys;
if (requireDerivedKeys)
{
SecurityTokenSerializer innerTokenSerializer = this.Factory.StandardsManager.SecurityTokenSerializer;
WSSecureConversation secureConversation = (innerTokenSerializer is WSSecurityTokenSerializer) ? ((WSSecurityTokenSerializer)innerTokenSerializer).SecureConversation : new WSSecurityTokenSerializer(this.Factory.MessageSecurityVersion.SecurityVersion).SecureConversation;
this.sessionStandardsManager = new SecurityStandardsManager(factory.MessageSecurityVersion, new DerivedKeyCachingSecurityTokenSerializer(2, false, secureConversation, innerTokenSerializer));
}
}
Object ThisLock
{
get
{
return thisLock;
}
}
public bool ReturnCorrelationState
{
get
{
return this.returnCorrelationState;
}
set
{
this.returnCorrelationState = value;
}
}
protected override bool PerformIncomingAndOutgoingMessageExpectationChecks
{
get { return false; }
}
SessionSymmetricMessageSecurityProtocolFactory Factory
{
get { return (SessionSymmetricMessageSecurityProtocolFactory)base.MessageSecurityProtocolFactory; }
}
public SecurityToken GetOutgoingSessionToken()
{
lock (ThisLock)
{
return this.outgoingSessionToken;
}
}
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.sessionStandardsManager.MessageSecurityVersion.SecureConversationVersion);
this.derivedSignatureToken = new DerivedKeySecurityToken(-1, 0,
this.Factory.OutgoingAlgorithmSuite.GetSignatureKeyDerivationLength(token, this.sessionStandardsManager.MessageSecurityVersion.SecureConversationVersion), null,
DerivedKeySecurityToken.DefaultNonceLength, token, this.Factory.SecurityTokenParameters.CreateKeyIdentifierClause(token, SecurityTokenReferenceStyle.External), derivationAlgorithm, SecurityUtils.GenerateId());
this.derivedEncryptionToken = new DerivedKeySecurityToken(-1, 0,
this.Factory.OutgoingAlgorithmSuite.GetEncryptionKeyDerivationLength(token, this.sessionStandardsManager.MessageSecurityVersion.SecureConversationVersion), null,
DerivedKeySecurityToken.DefaultNonceLength, token, this.Factory.SecurityTokenParameters.CreateKeyIdentifierClause(token, SecurityTokenReferenceStyle.External), derivationAlgorithm, SecurityUtils.GenerateId());
}
}
}
public void SetSessionTokenAuthenticator(UniqueId sessionId, SecurityTokenAuthenticator sessionTokenAuthenticator, SecurityTokenResolver sessionTokenResolver)
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
lock (ThisLock)
{
this.sessionId = sessionId;
this.sessionTokenAuthenticator = sessionTokenAuthenticator;
this.sessionTokenResolver = sessionTokenResolver;
List<SecurityTokenResolver> tmp = new List<SecurityTokenResolver>(1);
tmp.Add(this.sessionTokenResolver);
this.sessionResolverList = new ReadOnlyCollection<SecurityTokenResolver>(tmp);
}
}
void GetTokensForOutgoingMessages(out SecurityToken signingToken, out SecurityToken encryptionToken, out SecurityTokenParameters tokenParameters)
{
lock (ThisLock)
{
if (requireDerivedKeys)
{
signingToken = this.derivedSignatureToken;
encryptionToken = this.derivedEncryptionToken;
}
else
{
signingToken = encryptionToken = this.outgoingSessionToken;
}
}
tokenParameters = this.Factory.GetTokenParameters();
}
protected override IAsyncResult BeginSecureOutgoingMessageCore(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state)
{
SecurityToken signingToken;
SecurityToken encryptionToken;
SecurityTokenParameters tokenParameters;
this.GetTokensForOutgoingMessages(out signingToken, out encryptionToken, out tokenParameters);
SetUpDelayedSecurityExecution(ref message, signingToken, encryptionToken, tokenParameters, correlationState);
return new CompletedAsyncResult<Message>(message, callback, state);
}
protected override SecurityProtocolCorrelationState SecureOutgoingMessageCore(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
{
SecurityToken signingToken;
SecurityToken encryptionToken;
SecurityTokenParameters tokenParameters;
this.GetTokensForOutgoingMessages(out signingToken, out encryptionToken, out tokenParameters);
SetUpDelayedSecurityExecution(ref message, signingToken, encryptionToken, tokenParameters, correlationState);
return null;
}
protected override void EndSecureOutgoingMessageCore(IAsyncResult result, out Message message, out SecurityProtocolCorrelationState newCorrelationState)
{
message = CompletedAsyncResult<Message>.End(result);
newCorrelationState = null;
}
void SetUpDelayedSecurityExecution(ref Message message, SecurityToken signingToken, SecurityToken encryptionToken,
SecurityTokenParameters tokenParameters, SecurityProtocolCorrelationState correlationState)
{
string actor = string.Empty;
SendSecurityHeader securityHeader = ConfigureSendSecurityHeader(message, actor, null, correlationState);
if (this.Factory.ApplyIntegrity)
{
securityHeader.SetSigningToken(signingToken, tokenParameters);
}
if (Factory.ApplyConfidentiality)
{
securityHeader.SetEncryptionToken(encryptionToken, tokenParameters);
}
message = securityHeader.SetupExecution();
}
protected override SecurityProtocolCorrelationState VerifyIncomingMessageCore(ref Message message, string actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
{
SessionSymmetricMessageSecurityProtocolFactory factory = this.Factory;
IList<SupportingTokenAuthenticatorSpecification> supportingAuthenticators;
ReceiveSecurityHeader securityHeader = ConfigureReceiveSecurityHeader(message, string.Empty, correlationStates, (this.requireDerivedKeys) ? this.sessionStandardsManager : null, out supportingAuthenticators);
securityHeader.ConfigureSymmetricBindingServerReceiveHeader(this.sessionTokenAuthenticator, this.Factory.SecurityTokenParameters, supportingAuthenticators);
securityHeader.ConfigureOutOfBandTokenResolver(MergeOutOfBandResolvers(supportingAuthenticators, this.sessionResolverList));
// do not enforce key derivation requirement for Cancel messages due to WSE interop
securityHeader.EnforceDerivedKeyRequirement = (message.Headers.Action != factory.StandardsManager.SecureConversationDriver.CloseAction.Value);
ProcessSecurityHeader(securityHeader, ref message, null, timeout, correlationStates);
SecurityToken signingToken = securityHeader.SignatureToken;
SecurityContextSecurityToken signingSct = (signingToken as SecurityContextSecurityToken);
if (signingSct == null || signingSct.ContextId != sessionId)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.NoSessionTokenPresentInMessage)));
}
AttachRecipientSecurityProperty(message, signingToken, false, securityHeader.BasicSupportingTokens, securityHeader.EndorsingSupportingTokens, securityHeader.SignedEndorsingSupportingTokens,
securityHeader.SignedSupportingTokens, securityHeader.SecurityTokenAuthorizationPoliciesMapping);
return GetCorrelationState(null, securityHeader);
}
}
}

View File

@@ -0,0 +1,137 @@
//----------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Security.Tokens;
using System.Xml;
sealed class AcceptorSessionSymmetricTransportSecurityProtocol : TransportSecurityProtocol, IAcceptorSecuritySessionProtocol
{
SecurityToken outgoingSessionToken;
SecurityTokenAuthenticator sessionTokenAuthenticator;
SecurityTokenResolver sessionTokenResolver;
ReadOnlyCollection<SecurityTokenResolver> sessionTokenResolverList;
UniqueId sessionId;
Collection<SupportingTokenAuthenticatorSpecification> sessionTokenAuthenticatorSpecificationList;
bool requireDerivedKeys;
public AcceptorSessionSymmetricTransportSecurityProtocol(SessionSymmetricTransportSecurityProtocolFactory factory) : base(factory, null, null)
{
if (factory.ActAsInitiator == true)
{
Fx.Assert("This protocol can only be used at the recipient.");
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ProtocolMustBeRecipient, this.GetType().ToString())));
}
this.requireDerivedKeys = factory.SecurityTokenParameters.RequireDerivedKeys;
}
SessionSymmetricTransportSecurityProtocolFactory Factory
{
get { return (SessionSymmetricTransportSecurityProtocolFactory)this.SecurityProtocolFactory; }
}
public bool ReturnCorrelationState
{
get
{
return false;
}
set
{
}
}
public void SetSessionTokenAuthenticator(UniqueId sessionId, SecurityTokenAuthenticator sessionTokenAuthenticator, SecurityTokenResolver sessionTokenResolver)
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
this.sessionId = sessionId;
this.sessionTokenResolver = sessionTokenResolver;
Collection<SecurityTokenResolver> tmp = new Collection<SecurityTokenResolver>();
tmp.Add(this.sessionTokenResolver);
this.sessionTokenResolverList = new ReadOnlyCollection<SecurityTokenResolver>(tmp);
this.sessionTokenAuthenticator = sessionTokenAuthenticator;
SupportingTokenAuthenticatorSpecification spec = new SupportingTokenAuthenticatorSpecification(this.sessionTokenAuthenticator, this.sessionTokenResolver, SecurityTokenAttachmentMode.Endorsing, this.Factory.SecurityTokenParameters);
this.sessionTokenAuthenticatorSpecificationList = new Collection<SupportingTokenAuthenticatorSpecification>();
this.sessionTokenAuthenticatorSpecificationList.Add(spec);
}
public SecurityToken GetOutgoingSessionToken()
{
return this.outgoingSessionToken;
}
public void SetOutgoingSessionToken(SecurityToken token)
{
if (token == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
}
this.outgoingSessionToken = token;
}
protected override void VerifyIncomingMessageCore(ref Message message, TimeSpan timeout)
{
string actor = string.Empty; // message.Version.Envelope.UltimateDestinationActor;
ReceiveSecurityHeader securityHeader = this.Factory.StandardsManager.CreateReceiveSecurityHeader(message, actor,
this.Factory.IncomingAlgorithmSuite, MessageDirection.Input);
securityHeader.RequireMessageProtection = false;
securityHeader.ReaderQuotas = this.Factory.SecurityBindingElement.ReaderQuotas;
IList<SupportingTokenAuthenticatorSpecification> supportingAuthenticators = GetSupportingTokenAuthenticatorsAndSetExpectationFlags(this.Factory, message, securityHeader);
ReadOnlyCollection<SecurityTokenResolver> mergedTokenResolvers = MergeOutOfBandResolvers(supportingAuthenticators, this.sessionTokenResolverList);
if (supportingAuthenticators != null && supportingAuthenticators.Count > 0)
{
supportingAuthenticators = new List<SupportingTokenAuthenticatorSpecification>(supportingAuthenticators);
supportingAuthenticators.Insert(0, this.sessionTokenAuthenticatorSpecificationList[0]);
}
else
{
supportingAuthenticators = this.sessionTokenAuthenticatorSpecificationList;
}
securityHeader.ConfigureTransportBindingServerReceiveHeader(supportingAuthenticators);
securityHeader.ConfigureOutOfBandTokenResolver(mergedTokenResolvers);
securityHeader.ExpectEndorsingTokens = true;
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
securityHeader.ReplayDetectionEnabled = this.Factory.DetectReplays;
securityHeader.SetTimeParameters(this.Factory.NonceCache, this.Factory.ReplayWindow, this.Factory.MaxClockSkew);
// do not enforce key derivation requirement for Cancel messages due to WSE interop
securityHeader.EnforceDerivedKeyRequirement = (message.Headers.Action != this.Factory.StandardsManager.SecureConversationDriver.CloseAction.Value);
securityHeader.Process(timeoutHelper.RemainingTime(), SecurityUtils.GetChannelBindingFromMessage(message), this.Factory.ExtendedProtectionPolicy);
if (securityHeader.Timestamp == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.RequiredTimestampMissingInSecurityHeader)));
}
bool didSessionSctEndorse = false;
if (securityHeader.EndorsingSupportingTokens != null)
{
for (int i = 0; i < securityHeader.EndorsingSupportingTokens.Count; ++i)
{
SecurityContextSecurityToken signingSct = (securityHeader.EndorsingSupportingTokens[i] as SecurityContextSecurityToken);
if (signingSct != null && signingSct.ContextId == this.sessionId)
{
didSessionSctEndorse = true;
break;
}
}
}
if (!didSessionSctEndorse)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.NoSessionTokenPresentInMessage)));
}
message = securityHeader.ProcessedMessage;
AttachRecipientSecurityProperty(message, securityHeader.BasicSupportingTokens, securityHeader.EndorsingSupportingTokens,
securityHeader.SignedEndorsingSupportingTokens, securityHeader.SignedSupportingTokens, securityHeader.SecurityTokenAuthorizationPoliciesMapping);
base.OnIncomingMessageVerified(message);
}
}
}

View File

@@ -0,0 +1,137 @@
//----------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Runtime;
using System.Runtime.InteropServices;
using System.ServiceModel.Channels;
abstract class ApplySecurityAndSendAsyncResult<MessageSenderType> : AsyncResult
where MessageSenderType : class
{
readonly MessageSenderType channel;
readonly SecurityProtocol binding;
volatile bool secureOutgoingMessageDone;
static AsyncCallback sharedCallback = Fx.ThunkCallback(new AsyncCallback(SharedCallback));
SecurityProtocolCorrelationState newCorrelationState;
TimeoutHelper timeoutHelper;
public ApplySecurityAndSendAsyncResult(SecurityProtocol binding, MessageSenderType channel, TimeSpan timeout,
AsyncCallback callback, object state)
: base(callback, state)
{
this.binding = binding;
this.channel = channel;
this.timeoutHelper = new TimeoutHelper(timeout);
}
protected SecurityProtocolCorrelationState CorrelationState
{
get { return newCorrelationState; }
}
protected SecurityProtocol SecurityProtocol
{
get { return this.binding; }
}
protected void Begin(Message message, SecurityProtocolCorrelationState correlationState)
{
IAsyncResult result = this.binding.BeginSecureOutgoingMessage(message, timeoutHelper.RemainingTime(), correlationState, sharedCallback, this);
if (result.CompletedSynchronously)
{
this.binding.EndSecureOutgoingMessage(result, out message, out newCorrelationState);
bool completedSynchronously = this.OnSecureOutgoingMessageComplete(message);
if (completedSynchronously)
{
Complete(true);
}
}
}
protected static void OnEnd(ApplySecurityAndSendAsyncResult<MessageSenderType> self)
{
AsyncResult.End<ApplySecurityAndSendAsyncResult<MessageSenderType>>(self);
}
bool OnSecureOutgoingMessageComplete(Message message)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("message"));
}
this.secureOutgoingMessageDone = true;
IAsyncResult result = BeginSendCore(this.channel, message, timeoutHelper.RemainingTime(), sharedCallback, this);
if (!result.CompletedSynchronously)
{
return false;
}
EndSendCore(this.channel, result);
return this.OnSendComplete();
}
protected abstract IAsyncResult BeginSendCore(MessageSenderType channel, Message message, TimeSpan timeout, AsyncCallback callback, object state);
protected abstract void EndSendCore(MessageSenderType channel, IAsyncResult result);
bool OnSendComplete()
{
OnSendCompleteCore(timeoutHelper.RemainingTime());
return true;
}
protected abstract void OnSendCompleteCore(TimeSpan timeout);
static void SharedCallback(IAsyncResult result)
{
if (result == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("result"));
}
if (result.CompletedSynchronously)
{
return;
}
ApplySecurityAndSendAsyncResult<MessageSenderType> self = result.AsyncState as ApplySecurityAndSendAsyncResult<MessageSenderType>;
if (self == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.InvalidAsyncResult), "result"));
}
bool completeSelf = false;
Exception completionException = null;
try
{
if (!self.secureOutgoingMessageDone)
{
Message message;
self.binding.EndSecureOutgoingMessage(result, out message, out self.newCorrelationState);
completeSelf = self.OnSecureOutgoingMessageComplete(message);
}
else
{
self.EndSendCore(self.channel, result);
completeSelf = self.OnSendComplete();
}
}
#pragma warning suppress 56500 // covered by FxCOP
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
completeSelf = true;
completionException = e;
}
if (completeSelf)
{
self.Complete(false, completionException);
}
}
}
}

View File

@@ -0,0 +1,378 @@
//----------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IdentityModel.Policy;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Security.Tokens;
sealed class AsymmetricSecurityProtocol : MessageSecurityProtocol
{
SecurityTokenAuthenticator initiatorAsymmetricTokenAuthenticator;
SecurityTokenProvider initiatorAsymmetricTokenProvider;
SecurityTokenProvider initiatorCryptoTokenProvider;
public AsymmetricSecurityProtocol(AsymmetricSecurityProtocolFactory factory,
EndpointAddress target, Uri via)
: base(factory, target, via)
{
}
protected override bool DoAutomaticEncryptionMatch
{
get { return false; }
}
AsymmetricSecurityProtocolFactory Factory
{
get { return (AsymmetricSecurityProtocolFactory)base.MessageSecurityProtocolFactory; }
}
public SecurityTokenProvider InitiatorCryptoTokenProvider
{
get
{
this.CommunicationObject.ThrowIfNotOpened();
return this.initiatorCryptoTokenProvider;
}
}
public SecurityTokenAuthenticator InitiatorAsymmetricTokenAuthenticator
{
get
{
this.CommunicationObject.ThrowIfNotOpened();
return this.initiatorAsymmetricTokenAuthenticator;
}
}
public SecurityTokenProvider InitiatorAsymmetricTokenProvider
{
get
{
this.CommunicationObject.ThrowIfNotOpened();
return this.initiatorAsymmetricTokenProvider;
}
}
public override void OnOpen(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
base.OnOpen(timeoutHelper.RemainingTime());
if (this.Factory.ActAsInitiator)
{
if (this.Factory.ApplyIntegrity)
{
InitiatorServiceModelSecurityTokenRequirement requirement = CreateInitiatorSecurityTokenRequirement();
this.Factory.CryptoTokenParameters.InitializeSecurityTokenRequirement(requirement);
requirement.KeyUsage = SecurityKeyUsage.Signature;
requirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = MessageDirection.Output;
this.initiatorCryptoTokenProvider = this.Factory.SecurityTokenManager.CreateSecurityTokenProvider(requirement);
SecurityUtils.OpenTokenProviderIfRequired(this.initiatorCryptoTokenProvider, timeoutHelper.RemainingTime());
}
if (this.Factory.RequireIntegrity || this.Factory.ApplyConfidentiality)
{
InitiatorServiceModelSecurityTokenRequirement providerRequirement = CreateInitiatorSecurityTokenRequirement();
this.Factory.AsymmetricTokenParameters.InitializeSecurityTokenRequirement(providerRequirement);
providerRequirement.KeyUsage = SecurityKeyUsage.Exchange;
providerRequirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = (this.Factory.ApplyConfidentiality) ? MessageDirection.Output : MessageDirection.Input;
this.initiatorAsymmetricTokenProvider = this.Factory.SecurityTokenManager.CreateSecurityTokenProvider(providerRequirement);
SecurityUtils.OpenTokenProviderIfRequired(this.initiatorAsymmetricTokenProvider, timeoutHelper.RemainingTime());
InitiatorServiceModelSecurityTokenRequirement authenticatorRequirement = CreateInitiatorSecurityTokenRequirement();
this.Factory.AsymmetricTokenParameters.InitializeSecurityTokenRequirement(authenticatorRequirement);
authenticatorRequirement.IsOutOfBandToken = !this.Factory.AllowSerializedSigningTokenOnReply;
authenticatorRequirement.KeyUsage = SecurityKeyUsage.Exchange;
authenticatorRequirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = (this.Factory.ApplyConfidentiality) ? MessageDirection.Output : MessageDirection.Input;
// Create authenticator (we dont support out of band resolvers on the client side
SecurityTokenResolver outOfBandTokenResolver;
this.initiatorAsymmetricTokenAuthenticator = this.Factory.SecurityTokenManager.CreateSecurityTokenAuthenticator(authenticatorRequirement, out outOfBandTokenResolver);
SecurityUtils.OpenTokenAuthenticatorIfRequired(this.initiatorAsymmetricTokenAuthenticator, timeoutHelper.RemainingTime());
}
}
}
public override void OnAbort()
{
if (this.Factory.ActAsInitiator)
{
if (this.initiatorCryptoTokenProvider != null)
{
SecurityUtils.AbortTokenProviderIfRequired(this.initiatorCryptoTokenProvider);
}
if (this.initiatorAsymmetricTokenProvider != null)
{
SecurityUtils.AbortTokenProviderIfRequired(this.initiatorAsymmetricTokenProvider);
}
if (this.initiatorAsymmetricTokenAuthenticator != null)
{
SecurityUtils.AbortTokenAuthenticatorIfRequired(this.initiatorAsymmetricTokenAuthenticator);
}
}
base.OnAbort();
}
public override void OnClose(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
if (this.Factory.ActAsInitiator)
{
if (this.initiatorCryptoTokenProvider != null)
{
SecurityUtils.CloseTokenProviderIfRequired(this.initiatorCryptoTokenProvider, timeoutHelper.RemainingTime());
}
if (this.initiatorAsymmetricTokenProvider != null)
{
SecurityUtils.CloseTokenProviderIfRequired(this.initiatorAsymmetricTokenProvider, timeoutHelper.RemainingTime());
}
if (this.initiatorAsymmetricTokenAuthenticator != null)
{
SecurityUtils.CloseTokenAuthenticatorIfRequired(this.initiatorAsymmetricTokenAuthenticator, timeoutHelper.RemainingTime());
}
}
base.OnClose(timeoutHelper.RemainingTime());
}
protected override IAsyncResult BeginSecureOutgoingMessageCore(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state)
{
SecurityToken encryptingToken;
SecurityToken signingToken;
SecurityProtocolCorrelationState newCorrelationState;
IList<SupportingTokenSpecification> supportingTokens;
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
if (TryGetTokenSynchronouslyForOutgoingSecurity(message, correlationState, false, timeoutHelper.RemainingTime(), out encryptingToken, out signingToken, out supportingTokens, out newCorrelationState))
{
SetUpDelayedSecurityExecution(ref message, encryptingToken, signingToken, supportingTokens, GetSignatureConfirmationCorrelationState(correlationState, newCorrelationState));
return new CompletedAsyncResult<Message, SecurityProtocolCorrelationState>(message, newCorrelationState, callback, state);
}
else
{
if (this.Factory.ActAsInitiator == false)
{
Fx.Assert("Unexpected code path for server security application");
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SendingOutgoingmessageOnRecipient)));
}
AsymmetricSecurityProtocolFactory factory = this.Factory;
SecurityTokenProvider encProvider = factory.ApplyConfidentiality ? this.initiatorAsymmetricTokenProvider : null;
SecurityTokenProvider sigProvider = factory.ApplyIntegrity ? this.initiatorCryptoTokenProvider : null;
return new SecureOutgoingMessageAsyncResult(message, this,
encProvider, sigProvider, factory.ApplyConfidentiality, this.initiatorAsymmetricTokenAuthenticator, correlationState, timeoutHelper.RemainingTime(), callback, state);
}
}
protected override void EndSecureOutgoingMessageCore(IAsyncResult result, out Message message, out SecurityProtocolCorrelationState newCorrelationState)
{
if (result is CompletedAsyncResult<Message, SecurityProtocolCorrelationState>)
{
message = CompletedAsyncResult<Message, SecurityProtocolCorrelationState>.End(result, out newCorrelationState);
}
else
{
message = SecureOutgoingMessageAsyncResult.End(result, out newCorrelationState);
}
}
protected override SecurityProtocolCorrelationState SecureOutgoingMessageCore(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
{
SecurityToken encryptingToken;
SecurityToken signingToken;
SecurityProtocolCorrelationState newCorrelationState;
IList<SupportingTokenSpecification> supportingTokens;
TryGetTokenSynchronouslyForOutgoingSecurity(message, correlationState, true, timeout, out encryptingToken, out signingToken, out supportingTokens, out newCorrelationState);
SetUpDelayedSecurityExecution(ref message, encryptingToken, signingToken, supportingTokens, GetSignatureConfirmationCorrelationState(correlationState, newCorrelationState));
return newCorrelationState;
}
void SetUpDelayedSecurityExecution(ref Message message, SecurityToken encryptingToken, SecurityToken signingToken,
IList<SupportingTokenSpecification> supportingTokens, SecurityProtocolCorrelationState correlationState)
{
AsymmetricSecurityProtocolFactory factory = this.Factory;
string actor = string.Empty;
SendSecurityHeader securityHeader = ConfigureSendSecurityHeader(message, actor, supportingTokens, correlationState);
SecurityTokenParameters signingTokenParameters = (this.Factory.ActAsInitiator) ? this.Factory.CryptoTokenParameters : this.Factory.AsymmetricTokenParameters;
SecurityTokenParameters encryptionTokenParameters = (this.Factory.ActAsInitiator) ? this.Factory.AsymmetricTokenParameters : this.Factory.CryptoTokenParameters;
if (this.Factory.ApplyIntegrity || securityHeader.HasSignedTokens)
{
if (!this.Factory.ApplyIntegrity)
{
securityHeader.SignatureParts = MessagePartSpecification.NoParts;
}
securityHeader.SetSigningToken(signingToken, signingTokenParameters);
}
if (Factory.ApplyConfidentiality || securityHeader.HasEncryptedTokens)
{
if (!this.Factory.ApplyConfidentiality)
{
securityHeader.EncryptionParts = MessagePartSpecification.NoParts;
}
securityHeader.SetEncryptionToken(encryptingToken, encryptionTokenParameters);
}
message = securityHeader.SetupExecution();
}
void AttachRecipientSecurityProperty(Message message, SecurityToken initiatorToken, SecurityToken recipientToken, IList<SecurityToken> basicTokens, IList<SecurityToken> endorsingTokens,
IList<SecurityToken> signedEndorsingTokens, IList<SecurityToken> signedTokens, Dictionary<SecurityToken, ReadOnlyCollection<IAuthorizationPolicy>> tokenPoliciesMapping)
{
SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(message);
security.InitiatorToken = (initiatorToken != null) ? new SecurityTokenSpecification(initiatorToken, tokenPoliciesMapping[initiatorToken]) : null;
security.RecipientToken = (recipientToken != null) ? new SecurityTokenSpecification(recipientToken, EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance) : null;
AddSupportingTokenSpecification(security, basicTokens, endorsingTokens, signedEndorsingTokens, signedTokens, tokenPoliciesMapping);
security.ServiceSecurityContext = new ServiceSecurityContext(security.GetInitiatorTokenAuthorizationPolicies());
}
void DoIdentityCheckAndAttachInitiatorSecurityProperty(Message message, SecurityToken initiatorToken, SecurityToken recipientToken, ReadOnlyCollection<IAuthorizationPolicy> recipientTokenPolicies)
{
AuthorizationContext recipientAuthorizationContext = base.EnsureIncomingIdentity(message, recipientToken, recipientTokenPolicies);
SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(message);
security.InitiatorToken = (initiatorToken != null) ? new SecurityTokenSpecification(initiatorToken, EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance) : null;
security.RecipientToken = new SecurityTokenSpecification(recipientToken, recipientTokenPolicies);
security.ServiceSecurityContext = new ServiceSecurityContext(recipientAuthorizationContext, recipientTokenPolicies ?? EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance);
}
protected override SecurityProtocolCorrelationState VerifyIncomingMessageCore(ref Message message, string actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
{
AsymmetricSecurityProtocolFactory factory = this.Factory;
IList<SupportingTokenAuthenticatorSpecification> supportingAuthenticators;
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
ReceiveSecurityHeader securityHeader = ConfigureReceiveSecurityHeader(message, string.Empty, correlationStates, out supportingAuthenticators);
SecurityToken requiredReplySigningToken = null;
if (factory.ActAsInitiator)
{
SecurityToken encryptionToken = null;
SecurityToken receiverToken = null;
if (factory.RequireIntegrity)
{
receiverToken = GetToken(this.initiatorAsymmetricTokenProvider, null, timeoutHelper.RemainingTime());
requiredReplySigningToken = receiverToken;
}
if (factory.RequireConfidentiality)
{
encryptionToken = GetCorrelationToken(correlationStates);
if (!SecurityUtils.HasSymmetricSecurityKey(encryptionToken))
{
securityHeader.WrappedKeySecurityTokenAuthenticator = this.Factory.WrappedKeySecurityTokenAuthenticator;
}
}
SecurityTokenAuthenticator primaryTokenAuthenticator;
if (factory.AllowSerializedSigningTokenOnReply)
{
primaryTokenAuthenticator = this.initiatorAsymmetricTokenAuthenticator;
requiredReplySigningToken = null;
}
else
{
primaryTokenAuthenticator = null;
}
securityHeader.ConfigureAsymmetricBindingClientReceiveHeader(receiverToken,
factory.AsymmetricTokenParameters, encryptionToken, factory.CryptoTokenParameters,
primaryTokenAuthenticator);
}
else
{
SecurityToken wrappingToken;
if (this.Factory.RecipientAsymmetricTokenProvider != null && this.Factory.RequireConfidentiality)
{
wrappingToken = GetToken(factory.RecipientAsymmetricTokenProvider, null, timeoutHelper.RemainingTime());
}
else
{
wrappingToken = null;
}
securityHeader.ConfigureAsymmetricBindingServerReceiveHeader(this.Factory.RecipientCryptoTokenAuthenticator,
this.Factory.CryptoTokenParameters, wrappingToken, this.Factory.AsymmetricTokenParameters, supportingAuthenticators);
securityHeader.WrappedKeySecurityTokenAuthenticator = this.Factory.WrappedKeySecurityTokenAuthenticator;
securityHeader.ConfigureOutOfBandTokenResolver(MergeOutOfBandResolvers(supportingAuthenticators, this.Factory.RecipientOutOfBandTokenResolverList));
}
ProcessSecurityHeader(securityHeader, ref message, requiredReplySigningToken, timeoutHelper.RemainingTime(), correlationStates);
SecurityToken signingToken = securityHeader.SignatureToken;
SecurityToken encryptingToken = securityHeader.EncryptionToken;
if (factory.RequireIntegrity)
{
if (factory.ActAsInitiator)
{
ReadOnlyCollection<IAuthorizationPolicy> signingTokenPolicies = this.initiatorAsymmetricTokenAuthenticator.ValidateToken(signingToken);
EnsureNonWrappedToken(signingToken, message);
DoIdentityCheckAndAttachInitiatorSecurityProperty(message, encryptingToken, signingToken, signingTokenPolicies);
}
else
{
EnsureNonWrappedToken(signingToken, message);
AttachRecipientSecurityProperty(message, signingToken, encryptingToken, securityHeader.BasicSupportingTokens, securityHeader.EndorsingSupportingTokens, securityHeader.SignedEndorsingSupportingTokens,
securityHeader.SignedSupportingTokens, securityHeader.SecurityTokenAuthorizationPoliciesMapping);
}
}
return GetCorrelationState(signingToken, securityHeader);
}
bool TryGetTokenSynchronouslyForOutgoingSecurity(Message message, SecurityProtocolCorrelationState correlationState, bool isBlockingCall, TimeSpan timeout,
out SecurityToken encryptingToken, out SecurityToken signingToken, out IList<SupportingTokenSpecification> supportingTokens, out SecurityProtocolCorrelationState newCorrelationState)
{
AsymmetricSecurityProtocolFactory factory = this.Factory;
encryptingToken = null;
signingToken = null;
newCorrelationState = null;
supportingTokens = null;
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
if (factory.ActAsInitiator)
{
if (!isBlockingCall || !TryGetSupportingTokens(this.Factory, this.Target, this.Via, message, timeoutHelper.RemainingTime(), isBlockingCall, out supportingTokens))
{
return false;
}
if (factory.ApplyConfidentiality)
{
encryptingToken = GetTokenAndEnsureOutgoingIdentity(this.initiatorAsymmetricTokenProvider, true, timeoutHelper.RemainingTime(), this.initiatorAsymmetricTokenAuthenticator);
}
if (factory.ApplyIntegrity)
{
signingToken = GetToken(this.initiatorCryptoTokenProvider, this.Target, timeoutHelper.RemainingTime());
newCorrelationState = GetCorrelationState(signingToken);
}
}
else
{
if (factory.ApplyConfidentiality)
{
encryptingToken = GetCorrelationToken(correlationState);
}
if (factory.ApplyIntegrity)
{
signingToken = GetToken(factory.RecipientAsymmetricTokenProvider, null, timeoutHelper.RemainingTime());
}
}
return true;
}
sealed class SecureOutgoingMessageAsyncResult : GetTwoTokensAndSetUpSecurityAsyncResult
{
public SecureOutgoingMessageAsyncResult(Message m, AsymmetricSecurityProtocol binding,
SecurityTokenProvider primaryProvider, SecurityTokenProvider secondaryProvider, bool doIdentityChecks, SecurityTokenAuthenticator identityCheckAuthenticator,
SecurityProtocolCorrelationState correlationState, TimeSpan timeout, AsyncCallback callback, object state)
: base(m, binding, primaryProvider, secondaryProvider, doIdentityChecks, identityCheckAuthenticator, correlationState, timeout, callback, state)
{
Start();
}
protected override void OnBothGetTokenCallsDone(ref Message message, SecurityToken primaryToken, SecurityToken secondaryToken, TimeSpan timeout)
{
AsymmetricSecurityProtocol binding = (AsymmetricSecurityProtocol)this.Binding;
if (secondaryToken != null)
this.SetCorrelationToken(secondaryToken);
binding.SetUpDelayedSecurityExecution(ref message, primaryToken, secondaryToken, this.SupportingTokens, binding.GetSignatureConfirmationCorrelationState(OldCorrelationState, NewCorrelationState));
}
}
}
}

View File

@@ -0,0 +1,268 @@
//----------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Collections.ObjectModel;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security.Tokens;
class AsymmetricSecurityProtocolFactory : MessageSecurityProtocolFactory
{
SecurityTokenParameters cryptoTokenParameters;
SecurityTokenParameters asymmetricTokenParameters;
SecurityTokenProvider recipientAsymmetricTokenProvider;
ReadOnlyCollection<SecurityTokenResolver> recipientOutOfBandTokenResolverList;
SecurityTokenAuthenticator recipientCryptoTokenAuthenticator;
bool allowSerializedSigningTokenOnReply;
public AsymmetricSecurityProtocolFactory()
: base()
{
}
internal AsymmetricSecurityProtocolFactory(AsymmetricSecurityProtocolFactory factory)
: base(factory)
{
this.allowSerializedSigningTokenOnReply = factory.allowSerializedSigningTokenOnReply;
}
public bool AllowSerializedSigningTokenOnReply
{
get
{
return this.allowSerializedSigningTokenOnReply;
}
set
{
ThrowIfImmutable();
this.allowSerializedSigningTokenOnReply = value;
}
}
public SecurityTokenParameters AsymmetricTokenParameters
{
get
{
return this.asymmetricTokenParameters;
}
set
{
ThrowIfImmutable();
this.asymmetricTokenParameters = value;
}
}
public SecurityTokenProvider RecipientAsymmetricTokenProvider
{
get
{
this.CommunicationObject.ThrowIfNotOpened();
return this.recipientAsymmetricTokenProvider;
}
}
public SecurityTokenAuthenticator RecipientCryptoTokenAuthenticator
{
get
{
this.CommunicationObject.ThrowIfNotOpened();
return this.recipientCryptoTokenAuthenticator;
}
}
public ReadOnlyCollection<SecurityTokenResolver> RecipientOutOfBandTokenResolverList
{
get
{
this.CommunicationObject.ThrowIfNotOpened();
return this.recipientOutOfBandTokenResolverList;
}
}
public SecurityTokenParameters CryptoTokenParameters
{
get
{
return this.cryptoTokenParameters;
}
set
{
ThrowIfImmutable();
this.cryptoTokenParameters = value;
}
}
bool RequiresAsymmetricTokenProviderForForwardDirection
{
get
{
return ((this.ActAsInitiator && this.ApplyConfidentiality) || (!this.ActAsInitiator && this.RequireConfidentiality));
}
}
bool RequiresAsymmetricTokenProviderForReturnDirection
{
get
{
return ((this.ActAsInitiator && this.RequireIntegrity) || (!this.ActAsInitiator && this.ApplyIntegrity));
}
}
public override EndpointIdentity GetIdentityOfSelf()
{
if (this.SecurityTokenManager is IEndpointIdentityProvider && this.AsymmetricTokenParameters != null)
{
SecurityTokenRequirement requirement = CreateRecipientSecurityTokenRequirement();
this.AsymmetricTokenParameters.InitializeSecurityTokenRequirement(requirement);
return ((IEndpointIdentityProvider)this.SecurityTokenManager).GetIdentityOfSelf(requirement);
}
else
{
return base.GetIdentityOfSelf();
}
}
public override T GetProperty<T>()
{
if (typeof(T) == typeof(Collection<ISecurityContextSecurityTokenCache>))
{
Collection<ISecurityContextSecurityTokenCache> result = base.GetProperty<Collection<ISecurityContextSecurityTokenCache>>();
if (this.recipientCryptoTokenAuthenticator is ISecurityContextSecurityTokenCacheProvider)
{
result.Add(((ISecurityContextSecurityTokenCacheProvider)this.recipientCryptoTokenAuthenticator).TokenCache);
}
return (T) (object) (result);
}
else
{
return base.GetProperty<T>();
}
}
public override void OnClose(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
if (!this.ActAsInitiator)
{
if (this.recipientAsymmetricTokenProvider != null)
{
SecurityUtils.CloseTokenProviderIfRequired(this.recipientAsymmetricTokenProvider, timeoutHelper.RemainingTime());
}
if (this.recipientCryptoTokenAuthenticator != null)
{
SecurityUtils.CloseTokenAuthenticatorIfRequired(this.recipientCryptoTokenAuthenticator, timeoutHelper.RemainingTime());
}
}
base.OnClose(timeoutHelper.RemainingTime());
}
public override void OnAbort()
{
if (!this.ActAsInitiator)
{
if (this.recipientAsymmetricTokenProvider != null)
{
SecurityUtils.AbortTokenProviderIfRequired(this.recipientAsymmetricTokenProvider);
}
if (this.recipientCryptoTokenAuthenticator != null)
{
SecurityUtils.AbortTokenAuthenticatorIfRequired(this.recipientCryptoTokenAuthenticator);
}
}
base.OnAbort();
}
protected override SecurityProtocol OnCreateSecurityProtocol(EndpointAddress target, Uri via, object listenerSecurityState, TimeSpan timeout)
{
return new AsymmetricSecurityProtocol(this, target, via);
}
public override void OnOpen(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
base.OnOpen(timeoutHelper.RemainingTime());
// open forward direction
if (this.ActAsInitiator)
{
if (this.ApplyIntegrity)
{
if (this.CryptoTokenParameters == null)
{
OnPropertySettingsError("CryptoTokenParameters", true);
}
if (this.CryptoTokenParameters.RequireDerivedKeys)
{
this.ExpectKeyDerivation = true;
}
}
}
else
{
if (this.CryptoTokenParameters == null)
{
OnPropertySettingsError("CryptoTokenParameters", true);
}
if (this.CryptoTokenParameters.RequireDerivedKeys)
{
this.ExpectKeyDerivation = true;
}
SecurityTokenResolver resolver = null;
if (this.RequireIntegrity)
{
RecipientServiceModelSecurityTokenRequirement requirement = CreateRecipientSecurityTokenRequirement();
this.CryptoTokenParameters.InitializeSecurityTokenRequirement(requirement);
requirement.KeyUsage = SecurityKeyUsage.Signature;
requirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = MessageDirection.Input;
this.recipientCryptoTokenAuthenticator = this.SecurityTokenManager.CreateSecurityTokenAuthenticator(requirement, out resolver);
Open("RecipientCryptoTokenAuthenticator", true, this.recipientCryptoTokenAuthenticator, timeoutHelper.RemainingTime());
}
if (resolver != null)
{
Collection<SecurityTokenResolver> tmp = new Collection<SecurityTokenResolver>();
tmp.Add(resolver);
this.recipientOutOfBandTokenResolverList = new ReadOnlyCollection<SecurityTokenResolver>(tmp);
}
else
{
this.recipientOutOfBandTokenResolverList = EmptyReadOnlyCollection<SecurityTokenResolver>.Instance;
}
}
if (this.RequiresAsymmetricTokenProviderForForwardDirection || this.RequiresAsymmetricTokenProviderForReturnDirection)
{
if (this.AsymmetricTokenParameters == null)
{
OnPropertySettingsError("AsymmetricTokenParameters", this.RequiresAsymmetricTokenProviderForForwardDirection);
}
else if (this.AsymmetricTokenParameters.RequireDerivedKeys)
{
this.ExpectKeyDerivation = true;
}
if (!this.ActAsInitiator)
{
RecipientServiceModelSecurityTokenRequirement requirement = CreateRecipientSecurityTokenRequirement();
this.AsymmetricTokenParameters.InitializeSecurityTokenRequirement(requirement);
requirement.KeyUsage = (this.RequiresAsymmetricTokenProviderForForwardDirection) ? SecurityKeyUsage.Exchange : SecurityKeyUsage.Signature;
requirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = (this.RequiresAsymmetricTokenProviderForForwardDirection) ? MessageDirection.Input : MessageDirection.Output;
this.recipientAsymmetricTokenProvider = this.SecurityTokenManager.CreateSecurityTokenProvider(requirement);
Open("RecipientAsymmetricTokenProvider", this.RequiresAsymmetricTokenProviderForForwardDirection, this.recipientAsymmetricTokenProvider, timeoutHelper.RemainingTime());
}
}
if (this.ActAsInitiator && this.AllowSerializedSigningTokenOnReply && this.IdentityVerifier == null)
{
OnPropertySettingsError("IdentityVerifier", false);
}
}
}
}

View File

@@ -0,0 +1,28 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
public abstract class BasicSecurityProfileVersion
{
internal BasicSecurityProfileVersion() { }
public static BasicSecurityProfileVersion BasicSecurityProfile10
{
get { return BasicSecurityProfile10BasicSecurityProfileVersion.Instance; }
}
class BasicSecurityProfile10BasicSecurityProfileVersion : BasicSecurityProfileVersion
{
static BasicSecurityProfile10BasicSecurityProfileVersion instance = new BasicSecurityProfile10BasicSecurityProfileVersion();
public static BasicSecurityProfile10BasicSecurityProfileVersion Instance { get { return instance; } }
public override string ToString()
{
return "BasicSecurityProfile10";
}
}
}
}

View File

@@ -0,0 +1,89 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System;
using System.Xml;
using System.ServiceModel.Channels;
internal sealed class BinaryNegotiation
{
private byte[] negotiationData;
XmlDictionaryString valueTypeUriDictionaryString;
string valueTypeUri;
public BinaryNegotiation(
string valueTypeUri,
byte[] negotiationData)
{
if (valueTypeUri == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("valueTypeUri");
}
if (negotiationData == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("negotiationData");
}
this.valueTypeUriDictionaryString = null;
this.valueTypeUri = valueTypeUri;
this.negotiationData = negotiationData;
}
public BinaryNegotiation(
XmlDictionaryString valueTypeDictionaryString,
byte[] negotiationData)
{
if (valueTypeDictionaryString == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("valueTypeDictionaryString");
}
if (negotiationData == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("negotiationData");
}
this.valueTypeUriDictionaryString = valueTypeDictionaryString;
this.valueTypeUri = valueTypeDictionaryString.Value;
this.negotiationData = negotiationData;
}
public void Validate(XmlDictionaryString valueTypeUriDictionaryString)
{
if (this.valueTypeUri != valueTypeUriDictionaryString.Value)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.IncorrectBinaryNegotiationValueType, this.valueTypeUri)));
}
this.valueTypeUriDictionaryString = valueTypeUriDictionaryString;
}
public void WriteTo(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString ns, XmlDictionaryString valueTypeLocalName, XmlDictionaryString valueTypeNs)
{
writer.WriteStartElement(prefix, localName, ns);
writer.WriteStartAttribute(valueTypeLocalName, valueTypeNs);
if (valueTypeUriDictionaryString != null)
writer.WriteString(valueTypeUriDictionaryString);
else
writer.WriteString(valueTypeUri);
writer.WriteEndAttribute();
writer.WriteStartAttribute(XD.SecurityJan2004Dictionary.EncodingType, null);
writer.WriteString(XD.SecurityJan2004Dictionary.EncodingTypeValueBase64Binary);
writer.WriteEndAttribute();
writer.WriteBase64(this.negotiationData, 0, this.negotiationData.Length);
writer.WriteEndElement();
}
public string ValueTypeUri
{
get
{
return this.valueTypeUri;
}
}
public byte[] GetNegotiationData()
{
// avoid copying since this is internal and callers use it as read-only
return this.negotiationData;
}
}
}

View File

@@ -0,0 +1,380 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Net.Security;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Xml;
public class ChannelProtectionRequirements
{
ScopedMessagePartSpecification incomingSignatureParts;
ScopedMessagePartSpecification incomingEncryptionParts;
ScopedMessagePartSpecification outgoingSignatureParts;
ScopedMessagePartSpecification outgoingEncryptionParts;
bool isReadOnly;
public ChannelProtectionRequirements()
{
this.incomingSignatureParts = new ScopedMessagePartSpecification();
this.incomingEncryptionParts = new ScopedMessagePartSpecification();
this.outgoingSignatureParts = new ScopedMessagePartSpecification();
this.outgoingEncryptionParts = new ScopedMessagePartSpecification();
}
public bool IsReadOnly
{
get
{
return this.isReadOnly;
}
}
public ChannelProtectionRequirements(ChannelProtectionRequirements other)
{
if (other == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("other"));
this.incomingSignatureParts = new ScopedMessagePartSpecification(other.incomingSignatureParts);
this.incomingEncryptionParts = new ScopedMessagePartSpecification(other.incomingEncryptionParts);
this.outgoingSignatureParts = new ScopedMessagePartSpecification(other.outgoingSignatureParts);
this.outgoingEncryptionParts = new ScopedMessagePartSpecification(other.outgoingEncryptionParts);
}
internal ChannelProtectionRequirements(ChannelProtectionRequirements other, ProtectionLevel newBodyProtectionLevel)
{
if (other == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("other"));
this.incomingSignatureParts = new ScopedMessagePartSpecification(other.incomingSignatureParts, newBodyProtectionLevel != ProtectionLevel.None);
this.incomingEncryptionParts = new ScopedMessagePartSpecification(other.incomingEncryptionParts, newBodyProtectionLevel == ProtectionLevel.EncryptAndSign);
this.outgoingSignatureParts = new ScopedMessagePartSpecification(other.outgoingSignatureParts, newBodyProtectionLevel != ProtectionLevel.None);
this.outgoingEncryptionParts = new ScopedMessagePartSpecification(other.outgoingEncryptionParts, newBodyProtectionLevel == ProtectionLevel.EncryptAndSign);
}
public ScopedMessagePartSpecification IncomingSignatureParts
{
get
{
return this.incomingSignatureParts;
}
}
public ScopedMessagePartSpecification IncomingEncryptionParts
{
get
{
return this.incomingEncryptionParts;
}
}
public ScopedMessagePartSpecification OutgoingSignatureParts
{
get
{
return this.outgoingSignatureParts;
}
}
public ScopedMessagePartSpecification OutgoingEncryptionParts
{
get
{
return this.outgoingEncryptionParts;
}
}
public void Add(ChannelProtectionRequirements protectionRequirements)
{
this.Add(protectionRequirements, false);
}
public void Add(ChannelProtectionRequirements protectionRequirements, bool channelScopeOnly)
{
if (protectionRequirements == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("protectionRequirements"));
if (protectionRequirements.incomingSignatureParts != null)
this.incomingSignatureParts.AddParts(protectionRequirements.incomingSignatureParts.ChannelParts);
if (protectionRequirements.incomingEncryptionParts != null)
this.incomingEncryptionParts.AddParts(protectionRequirements.incomingEncryptionParts.ChannelParts);
if (protectionRequirements.outgoingSignatureParts != null)
this.outgoingSignatureParts.AddParts(protectionRequirements.outgoingSignatureParts.ChannelParts);
if (protectionRequirements.outgoingEncryptionParts != null)
this.outgoingEncryptionParts.AddParts(protectionRequirements.outgoingEncryptionParts.ChannelParts);
if (!channelScopeOnly)
{
AddActionParts(this.incomingSignatureParts, protectionRequirements.incomingSignatureParts);
AddActionParts(this.incomingEncryptionParts, protectionRequirements.incomingEncryptionParts);
AddActionParts(this.outgoingSignatureParts, protectionRequirements.outgoingSignatureParts);
AddActionParts(this.outgoingEncryptionParts, protectionRequirements.outgoingEncryptionParts);
}
}
static void AddActionParts(ScopedMessagePartSpecification to, ScopedMessagePartSpecification from)
{
foreach (string action in from.Actions)
{
MessagePartSpecification p;
if (from.TryGetParts(action, true, out p))
to.AddParts(p, action);
}
}
public void MakeReadOnly()
{
if (!this.isReadOnly)
{
this.incomingSignatureParts.MakeReadOnly();
this.incomingEncryptionParts.MakeReadOnly();
this.outgoingSignatureParts.MakeReadOnly();
this.outgoingEncryptionParts.MakeReadOnly();
this.isReadOnly = true;
}
}
public ChannelProtectionRequirements CreateInverse()
{
ChannelProtectionRequirements result = new ChannelProtectionRequirements();
result.Add(this, true);
result.incomingSignatureParts = new ScopedMessagePartSpecification(this.OutgoingSignatureParts);
result.outgoingSignatureParts = new ScopedMessagePartSpecification(this.IncomingSignatureParts);
result.incomingEncryptionParts = new ScopedMessagePartSpecification(this.OutgoingEncryptionParts);
result.outgoingEncryptionParts = new ScopedMessagePartSpecification(this.IncomingEncryptionParts);
return result;
}
internal static ChannelProtectionRequirements CreateFromContract(ContractDescription contract, ISecurityCapabilities bindingElement, bool isForClient)
{
return CreateFromContract(contract, bindingElement.SupportedRequestProtectionLevel, bindingElement.SupportedResponseProtectionLevel, isForClient);
}
static MessagePartSpecification UnionMessagePartSpecifications(ScopedMessagePartSpecification actionParts)
{
MessagePartSpecification result = new MessagePartSpecification(false);
foreach (string action in actionParts.Actions)
{
MessagePartSpecification parts;
if (actionParts.TryGetParts(action, out parts))
{
if (parts.IsBodyIncluded)
{
result.IsBodyIncluded = true;
}
foreach (XmlQualifiedName headerType in parts.HeaderTypes)
{
if (!result.IsHeaderIncluded(headerType.Name, headerType.Namespace))
{
result.HeaderTypes.Add(headerType);
}
}
}
}
return result;
}
internal static ChannelProtectionRequirements CreateFromContractAndUnionResponseProtectionRequirements(ContractDescription contract, ISecurityCapabilities bindingElement, bool isForClient)
{
ChannelProtectionRequirements contractRequirements = CreateFromContract(contract, bindingElement.SupportedRequestProtectionLevel, bindingElement.SupportedResponseProtectionLevel, isForClient);
// union all the protection requirements for the response actions
ChannelProtectionRequirements result = new ChannelProtectionRequirements();
//if (isForClient)
//{
// result.IncomingEncryptionParts.AddParts(UnionMessagePartSpecifications(contractRequirements.IncomingEncryptionParts), MessageHeaders.WildcardAction);
// result.IncomingSignatureParts.AddParts(UnionMessagePartSpecifications(contractRequirements.IncomingSignatureParts), MessageHeaders.WildcardAction);
// contractRequirements.OutgoingEncryptionParts.CopyTo(result.OutgoingEncryptionParts);
// contractRequirements.OutgoingSignatureParts.CopyTo(result.OutgoingSignatureParts);
//}
//else
//{
result.OutgoingEncryptionParts.AddParts(UnionMessagePartSpecifications(contractRequirements.OutgoingEncryptionParts), MessageHeaders.WildcardAction);
result.OutgoingSignatureParts.AddParts(UnionMessagePartSpecifications(contractRequirements.OutgoingSignatureParts), MessageHeaders.WildcardAction);
contractRequirements.IncomingEncryptionParts.CopyTo(result.IncomingEncryptionParts);
contractRequirements.IncomingSignatureParts.CopyTo(result.IncomingSignatureParts);
//}
return result;
}
internal static ChannelProtectionRequirements CreateFromContract(ContractDescription contract, ProtectionLevel defaultRequestProtectionLevel, ProtectionLevel defaultResponseProtectionLevel, bool isForClient)
{
if (contract == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("contract"));
ChannelProtectionRequirements requirements = new ChannelProtectionRequirements();
ProtectionLevel contractScopeDefaultRequestProtectionLevel;
ProtectionLevel contractScopeDefaultResponseProtectionLevel;
if (contract.HasProtectionLevel)
{
contractScopeDefaultRequestProtectionLevel = contract.ProtectionLevel;
contractScopeDefaultResponseProtectionLevel = contract.ProtectionLevel;
}
else
{
contractScopeDefaultRequestProtectionLevel = defaultRequestProtectionLevel;
contractScopeDefaultResponseProtectionLevel = defaultResponseProtectionLevel;
}
foreach (OperationDescription operation in contract.Operations)
{
ProtectionLevel operationScopeDefaultRequestProtectionLevel;
ProtectionLevel operationScopeDefaultResponseProtectionLevel;
if (operation.HasProtectionLevel)
{
operationScopeDefaultRequestProtectionLevel = operation.ProtectionLevel;
operationScopeDefaultResponseProtectionLevel = operation.ProtectionLevel;
}
else
{
operationScopeDefaultRequestProtectionLevel = contractScopeDefaultRequestProtectionLevel;
operationScopeDefaultResponseProtectionLevel = contractScopeDefaultResponseProtectionLevel;
}
foreach (MessageDescription message in operation.Messages)
{
ProtectionLevel messageScopeDefaultProtectionLevel;
if (message.HasProtectionLevel)
{
messageScopeDefaultProtectionLevel = message.ProtectionLevel;
}
else if (message.Direction == MessageDirection.Input)
{
messageScopeDefaultProtectionLevel = operationScopeDefaultRequestProtectionLevel;
}
else
{
messageScopeDefaultProtectionLevel = operationScopeDefaultResponseProtectionLevel;
}
MessagePartSpecification signedParts = new MessagePartSpecification();
MessagePartSpecification encryptedParts = new MessagePartSpecification();
// determine header protection requirements for message
foreach (MessageHeaderDescription header in message.Headers)
{
AddHeaderProtectionRequirements(header, signedParts, encryptedParts, messageScopeDefaultProtectionLevel);
}
// determine body protection requirements for message
ProtectionLevel bodyProtectionLevel;
if (message.Body.Parts.Count > 0)
{
// initialize the body protection level to none. all the body parts will be
// unioned to get the effective body protection level
bodyProtectionLevel = ProtectionLevel.None;
}
else if (message.Body.ReturnValue != null)
{
if (!(message.Body.ReturnValue.GetType().Equals(typeof(MessagePartDescription))))
{
Fx.Assert("Only body return values are supported currently");
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.OnlyBodyReturnValuesSupported)));
}
MessagePartDescription desc = message.Body.ReturnValue;
bodyProtectionLevel = desc.HasProtectionLevel ? desc.ProtectionLevel : messageScopeDefaultProtectionLevel;
}
else
{
bodyProtectionLevel = messageScopeDefaultProtectionLevel;
}
// determine body protection requirements for message
if (message.Body.Parts.Count > 0)
{
foreach (MessagePartDescription body in message.Body.Parts)
{
ProtectionLevel partProtectionLevel = body.HasProtectionLevel ? body.ProtectionLevel : messageScopeDefaultProtectionLevel;
bodyProtectionLevel = ProtectionLevelHelper.Max(bodyProtectionLevel, partProtectionLevel);
if (bodyProtectionLevel == ProtectionLevel.EncryptAndSign)
break;
}
}
if (bodyProtectionLevel != ProtectionLevel.None)
{
signedParts.IsBodyIncluded = true;
if (bodyProtectionLevel == ProtectionLevel.EncryptAndSign)
encryptedParts.IsBodyIncluded = true;
}
// add requirements for message
if (message.Direction == MessageDirection.Input)
{
requirements.IncomingSignatureParts.AddParts(signedParts, message.Action);
requirements.IncomingEncryptionParts.AddParts(encryptedParts, message.Action);
}
else
{
requirements.OutgoingSignatureParts.AddParts(signedParts, message.Action);
requirements.OutgoingEncryptionParts.AddParts(encryptedParts, message.Action);
}
}
if (operation.Faults != null)
{
if (operation.IsServerInitiated())
{
AddFaultProtectionRequirements(operation.Faults, requirements, operationScopeDefaultRequestProtectionLevel, true);
}
else
{
AddFaultProtectionRequirements(operation.Faults, requirements, operationScopeDefaultResponseProtectionLevel, false);
}
}
}
return requirements;
}
static void AddHeaderProtectionRequirements(MessageHeaderDescription header, MessagePartSpecification signedParts,
MessagePartSpecification encryptedParts, ProtectionLevel defaultProtectionLevel)
{
ProtectionLevel p = header.HasProtectionLevel ? header.ProtectionLevel : defaultProtectionLevel;
if (p != ProtectionLevel.None)
{
XmlQualifiedName headerName = new XmlQualifiedName(header.Name, header.Namespace);
signedParts.HeaderTypes.Add(headerName);
if (p == ProtectionLevel.EncryptAndSign)
encryptedParts.HeaderTypes.Add(headerName);
}
}
static void AddFaultProtectionRequirements(FaultDescriptionCollection faults, ChannelProtectionRequirements requirements, ProtectionLevel defaultProtectionLevel, bool addToIncoming)
{
if (faults == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("faults"));
if (requirements == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("requirements"));
foreach (FaultDescription fault in faults)
{
MessagePartSpecification signedParts = new MessagePartSpecification();
MessagePartSpecification encryptedParts = new MessagePartSpecification();
ProtectionLevel p = fault.HasProtectionLevel ? fault.ProtectionLevel : defaultProtectionLevel;
if (p != ProtectionLevel.None)
{
signedParts.IsBodyIncluded = true;
if (p == ProtectionLevel.EncryptAndSign)
{
encryptedParts.IsBodyIncluded = true;
}
}
if (addToIncoming)
{
requirements.IncomingSignatureParts.AddParts(signedParts, fault.Action);
requirements.IncomingEncryptionParts.AddParts(encryptedParts, fault.Action);
}
else
{
requirements.OutgoingSignatureParts.AddParts(signedParts, fault.Action);
requirements.OutgoingEncryptionParts.AddParts(encryptedParts, fault.Action);
}
}
}
}
}

View File

@@ -0,0 +1,357 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Collections;
using System.Collections.Generic;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Reflection;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
using System.IdentityModel.Tokens;
using System.Text;
using System.Xml;
using System.Diagnostics;
using System.Security.Cryptography;
using Psha1DerivedKeyGenerator = System.IdentityModel.Psha1DerivedKeyGenerator;
using CryptoAlgorithms = System.IdentityModel.CryptoHelper;
static class CryptoHelper
{
static byte[] emptyBuffer;
static readonly RandomNumberGenerator random = new RNGCryptoServiceProvider();
enum CryptoAlgorithmType
{
Unknown,
Symmetric,
Asymmetric
}
internal static byte[] EmptyBuffer
{
get
{
if (emptyBuffer == null)
{
byte[] tmp = new byte[0];
emptyBuffer = tmp;
}
return emptyBuffer;
}
}
internal static HashAlgorithm NewSha1HashAlgorithm()
{
return CryptoHelper.CreateHashAlgorithm(SecurityAlgorithms.Sha1Digest);
}
internal static HashAlgorithm NewSha256HashAlgorithm()
{
return CryptoHelper.CreateHashAlgorithm(SecurityAlgorithms.Sha256Digest);
}
internal static HashAlgorithm CreateHashAlgorithm(string digestMethod)
{
object algorithmObject = CryptoAlgorithms.GetAlgorithmFromConfig(digestMethod);
if (algorithmObject != null)
{
HashAlgorithm hashAlgorithm = algorithmObject as HashAlgorithm;
if (hashAlgorithm != null)
return hashAlgorithm;
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.CustomCryptoAlgorithmIsNotValidHashAlgorithm, digestMethod)));
}
switch (digestMethod)
{
case SecurityAlgorithms.Sha1Digest:
if (SecurityUtilsEx.RequiresFipsCompliance)
return new SHA1CryptoServiceProvider();
else
return new SHA1Managed();
case SecurityAlgorithms.Sha256Digest:
if (SecurityUtilsEx.RequiresFipsCompliance)
return new SHA256CryptoServiceProvider();
else
return new SHA256Managed();
default:
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.UnsupportedCryptoAlgorithm, digestMethod)));
}
}
internal static HashAlgorithm CreateHashForAsymmetricSignature(string signatureMethod)
{
object algorithmObject = CryptoAlgorithms.GetAlgorithmFromConfig(signatureMethod);
if (algorithmObject != null)
{
HashAlgorithm hashAlgorithm;
SignatureDescription signatureDescription = algorithmObject as SignatureDescription;
if (signatureDescription != null)
{
hashAlgorithm = signatureDescription.CreateDigest();
if (hashAlgorithm != null)
return hashAlgorithm;
}
hashAlgorithm = algorithmObject as HashAlgorithm;
if (hashAlgorithm != null)
return hashAlgorithm;
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.CustomCryptoAlgorithmIsNotValidAsymmetricSignature, signatureMethod)));
}
switch (signatureMethod)
{
case SecurityAlgorithms.RsaSha1Signature:
case SecurityAlgorithms.DsaSha1Signature:
if (SecurityUtilsEx.RequiresFipsCompliance)
return new SHA1CryptoServiceProvider();
else
return new SHA1Managed();
case SecurityAlgorithms.RsaSha256Signature:
if (SecurityUtilsEx.RequiresFipsCompliance)
return new SHA256CryptoServiceProvider();
else
return new SHA256Managed();
default:
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.UnsupportedCryptoAlgorithm, signatureMethod)));
}
}
internal static byte[] ExtractIVAndDecrypt(SymmetricAlgorithm algorithm, byte[] cipherText, int offset, int count)
{
if (cipherText == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("cipherText");
}
if (count < 0 || count > cipherText.Length)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeInRange, 0, cipherText.Length)));
}
if (offset < 0 || offset > cipherText.Length - count)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeInRange, 0, cipherText.Length - count)));
}
int ivSize = algorithm.BlockSize / 8;
byte[] iv = new byte[ivSize];
Buffer.BlockCopy(cipherText, offset, iv, 0, iv.Length);
algorithm.Padding = PaddingMode.ISO10126;
algorithm.Mode = CipherMode.CBC;
try
{
using (ICryptoTransform decrTransform = algorithm.CreateDecryptor(algorithm.Key, iv))
{
return decrTransform.TransformFinalBlock(cipherText, offset + iv.Length, count - iv.Length);
}
}
catch (CryptographicException ex)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.DecryptionFailed), ex));
}
}
internal static void FillRandomBytes(byte[] buffer)
{
random.GetBytes(buffer);
}
static CryptoAlgorithmType GetAlgorithmType(string algorithm)
{
object algorithmObject = null;
try
{
algorithmObject = CryptoAlgorithms.GetAlgorithmFromConfig(algorithm);
}
catch (InvalidOperationException)
{
algorithmObject = null;
// We ---- the exception and continue.
}
if (algorithmObject != null)
{
SymmetricAlgorithm symmetricAlgorithm = algorithmObject as SymmetricAlgorithm;
KeyedHashAlgorithm keyedHashAlgorithm = algorithmObject as KeyedHashAlgorithm;
if (symmetricAlgorithm != null || keyedHashAlgorithm != null)
return CryptoAlgorithmType.Symmetric;
// NOTE: A KeyedHashAlgorithm is symmetric in nature.
AsymmetricAlgorithm asymmetricAlgorithm = algorithmObject as AsymmetricAlgorithm;
SignatureDescription signatureDescription = algorithmObject as SignatureDescription;
if (asymmetricAlgorithm != null || signatureDescription != null)
return CryptoAlgorithmType.Asymmetric;
return CryptoAlgorithmType.Unknown;
}
switch (algorithm)
{
case SecurityAlgorithms.DsaSha1Signature:
case SecurityAlgorithms.RsaSha1Signature:
case SecurityAlgorithms.RsaSha256Signature:
case SecurityAlgorithms.RsaOaepKeyWrap:
case SecurityAlgorithms.RsaV15KeyWrap:
return CryptoAlgorithmType.Asymmetric;
case SecurityAlgorithms.HmacSha1Signature:
case SecurityAlgorithms.HmacSha256Signature:
case SecurityAlgorithms.Aes128Encryption:
case SecurityAlgorithms.Aes192Encryption:
case SecurityAlgorithms.Aes256Encryption:
case SecurityAlgorithms.TripleDesEncryption:
case SecurityAlgorithms.Aes128KeyWrap:
case SecurityAlgorithms.Aes192KeyWrap:
case SecurityAlgorithms.Aes256KeyWrap:
case SecurityAlgorithms.TripleDesKeyWrap:
case SecurityAlgorithms.Psha1KeyDerivation:
case SecurityAlgorithms.Psha1KeyDerivationDec2005:
return CryptoAlgorithmType.Symmetric;
default:
return CryptoAlgorithmType.Unknown;
}
}
internal static byte[] GenerateIVAndEncrypt(SymmetricAlgorithm algorithm, byte[] plainText, int offset, int count)
{
byte[] iv;
byte[] cipherText;
GenerateIVAndEncrypt(algorithm, new ArraySegment<byte>(plainText, offset, count), out iv, out cipherText);
byte[] output = DiagnosticUtility.Utility.AllocateByteArray(checked(iv.Length + cipherText.Length));
Buffer.BlockCopy(iv, 0, output, 0, iv.Length);
Buffer.BlockCopy(cipherText, 0, output, iv.Length, cipherText.Length);
return output;
}
internal static void GenerateIVAndEncrypt(SymmetricAlgorithm algorithm, ArraySegment<byte> plainText, out byte[] iv, out byte[] cipherText)
{
int ivSize = algorithm.BlockSize / 8;
iv = new byte[ivSize];
FillRandomBytes(iv);
algorithm.Padding = PaddingMode.PKCS7;
algorithm.Mode = CipherMode.CBC;
using (ICryptoTransform encrTransform = algorithm.CreateEncryptor(algorithm.Key, iv))
{
cipherText = encrTransform.TransformFinalBlock(plainText.Array, plainText.Offset, plainText.Count);
}
}
internal static bool IsEqual(byte[] a, byte[] b)
{
if (a == null || b == null || a.Length != b.Length)
{
return false;
}
for (int i = 0; i < a.Length; i++)
{
if (a[i] != b[i])
{
return false;
}
}
return true;
}
internal static bool IsSymmetricAlgorithm(string algorithm)
{
return GetAlgorithmType(algorithm) == CryptoAlgorithmType.Symmetric;
}
internal static bool IsSymmetricSupportedAlgorithm(string algorithm, int keySize)
{
bool found = false;
object algorithmObject = null;
try
{
algorithmObject = CryptoAlgorithms.GetAlgorithmFromConfig(algorithm);
}
catch (InvalidOperationException)
{
algorithmObject = null;
// We ---- the exception and continue.
}
if (algorithmObject != null)
{
SymmetricAlgorithm symmetricAlgorithm = algorithmObject as SymmetricAlgorithm;
KeyedHashAlgorithm keyedHashAlgorithm = algorithmObject as KeyedHashAlgorithm;
if (symmetricAlgorithm != null || keyedHashAlgorithm != null)
found = true;
}
switch (algorithm)
{
case SecurityAlgorithms.DsaSha1Signature:
case SecurityAlgorithms.RsaSha1Signature:
case SecurityAlgorithms.RsaSha256Signature:
case SecurityAlgorithms.RsaOaepKeyWrap:
case SecurityAlgorithms.RsaV15KeyWrap:
return false;
case SecurityAlgorithms.HmacSha1Signature:
case SecurityAlgorithms.HmacSha256Signature:
case SecurityAlgorithms.Psha1KeyDerivation:
case SecurityAlgorithms.Psha1KeyDerivationDec2005:
return true;
case SecurityAlgorithms.Aes128Encryption:
case SecurityAlgorithms.Aes128KeyWrap:
return keySize == 128;
case SecurityAlgorithms.Aes192Encryption:
case SecurityAlgorithms.Aes192KeyWrap:
return keySize == 192;
case SecurityAlgorithms.Aes256Encryption:
case SecurityAlgorithms.Aes256KeyWrap:
return keySize == 256;
case SecurityAlgorithms.TripleDesEncryption:
case SecurityAlgorithms.TripleDesKeyWrap:
return keySize == 128 || keySize == 192;
default:
if (found)
return true;
return false;
}
}
internal static void ValidateBufferBounds(Array buffer, int offset, int count)
{
if (buffer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
}
if (count < 0 || count > buffer.Length)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeInRange, 0, buffer.Length)));
}
if (offset < 0 || offset > buffer.Length - count)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeInRange, 0, buffer.Length - count)));
}
}
internal static void ValidateSymmetricKeyLength(int keyLength, SecurityAlgorithmSuite algorithmSuite)
{
if (!algorithmSuite.IsSymmetricKeyLengthSupported(keyLength))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new ArgumentOutOfRangeException("algorithmSuite",
SR.GetString(SR.UnsupportedKeyLength, keyLength, algorithmSuite.ToString())));
}
if (keyLength % 8 != 0)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new ArgumentOutOfRangeException("algorithmSuite",
SR.GetString(SR.KeyLengthMustBeMultipleOfEight, keyLength)));
}
}
}
}

View File

@@ -0,0 +1,92 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Text;
using System.Security.Cryptography;
public class DataProtectionSecurityStateEncoder : SecurityStateEncoder
{
byte[] entropy;
bool useCurrentUserProtectionScope;
public DataProtectionSecurityStateEncoder()
: this(true)
{
// empty
}
public DataProtectionSecurityStateEncoder(bool useCurrentUserProtectionScope)
: this(useCurrentUserProtectionScope, null)
{ }
public DataProtectionSecurityStateEncoder(bool useCurrentUserProtectionScope, byte[] entropy)
{
this.useCurrentUserProtectionScope = useCurrentUserProtectionScope;
if (entropy == null)
{
this.entropy = null;
}
else
{
this.entropy = DiagnosticUtility.Utility.AllocateByteArray(entropy.Length);
Buffer.BlockCopy(entropy, 0, this.entropy, 0, entropy.Length);
}
}
public bool UseCurrentUserProtectionScope
{
get
{
return this.useCurrentUserProtectionScope;
}
}
public byte[] GetEntropy()
{
byte[] result = null;
if (this.entropy != null)
{
result = DiagnosticUtility.Utility.AllocateByteArray(this.entropy.Length);
Buffer.BlockCopy(this.entropy, 0, result, 0, this.entropy.Length);
}
return result;
}
public override string ToString()
{
StringBuilder result = new StringBuilder();
result.Append(this.GetType().ToString());
result.AppendFormat("{0} UseCurrentUserProtectionScope={1}", Environment.NewLine, this.useCurrentUserProtectionScope);
result.AppendFormat("{0} Entropy Length={1}", Environment.NewLine, (this.entropy == null) ? 0 : this.entropy.Length);
return result.ToString();
}
protected internal override byte[] DecodeSecurityState( byte[] data )
{
try
{
return ProtectedData.Unprotect(data, this.entropy, (this.useCurrentUserProtectionScope) ? DataProtectionScope.CurrentUser : DataProtectionScope.LocalMachine);
}
catch (CryptographicException exception)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.SecurityStateEncoderDecodingFailure), exception));
}
}
protected internal override byte[] EncodeSecurityState( byte[] data )
{
try
{
return ProtectedData.Protect(data, this.entropy, (this.useCurrentUserProtectionScope) ? DataProtectionScope.CurrentUser : DataProtectionScope.LocalMachine);
}
catch (CryptographicException exception)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.SecurityStateEncoderEncodingFailure), exception));
}
}
}
}

View File

@@ -0,0 +1,133 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Xml;
using System.ServiceModel.Channels;
using System.ServiceModel;
sealed class DecryptedHeader : ReadableMessageHeader
{
XmlDictionaryReader cachedReader;
readonly byte[] decryptedBuffer;
readonly string id;
readonly string name;
readonly string namespaceUri;
readonly string actor;
readonly bool mustUnderstand;
readonly bool relay;
readonly bool isRefParam;
readonly MessageVersion version;
readonly XmlAttributeHolder[] envelopeAttributes;
readonly XmlAttributeHolder[] headerAttributes;
readonly XmlDictionaryReaderQuotas quotas;
public DecryptedHeader(byte[] decryptedBuffer,
XmlAttributeHolder[] envelopeAttributes, XmlAttributeHolder[] headerAttributes,
MessageVersion version, SignatureTargetIdManager idManager, XmlDictionaryReaderQuotas quotas)
{
if (quotas == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("quotas");
this.decryptedBuffer = decryptedBuffer;
this.version = version;
this.envelopeAttributes = envelopeAttributes;
this.headerAttributes = headerAttributes;
this.quotas = quotas;
XmlDictionaryReader reader = CreateReader();
reader.MoveToStartElement();
this.name = reader.LocalName;
this.namespaceUri = reader.NamespaceURI;
MessageHeader.GetHeaderAttributes(reader, version, out this.actor, out this.mustUnderstand, out this.relay, out this.isRefParam);
this.id = idManager.ExtractId(reader);
this.cachedReader = reader;
}
public override string Actor
{
get
{
return this.actor;
}
}
public string Id
{
get
{
return this.id;
}
}
public override bool IsReferenceParameter
{
get
{
return this.isRefParam;
}
}
public override bool MustUnderstand
{
get
{
return this.mustUnderstand;
}
}
public override string Name
{
get
{
return this.name;
}
}
public override string Namespace
{
get
{
return this.namespaceUri;
}
}
public override bool Relay
{
get
{
return this.relay;
}
}
XmlDictionaryReader CreateReader()
{
return ContextImportHelper.CreateSplicedReader(
this.decryptedBuffer,
this.envelopeAttributes,
this.headerAttributes, null, this.quotas);
}
public override XmlDictionaryReader GetHeaderReader()
{
if (this.cachedReader != null)
{
XmlDictionaryReader cachedReader = this.cachedReader;
this.cachedReader = null;
return cachedReader;
}
XmlDictionaryReader reader = CreateReader();
reader.MoveToContent();
return reader;
}
public override bool IsMessageVersionSupported(MessageVersion messageVersion)
{
return this.version.Equals( messageVersion );
}
}
}

View File

@@ -0,0 +1,82 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Xml;
using System.ServiceModel.Channels;
using System.ServiceModel;
abstract class DelegatingHeader : MessageHeader
{
MessageHeader innerHeader;
protected DelegatingHeader(MessageHeader innerHeader)
{
if (innerHeader == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("innerHeader");
}
this.innerHeader = innerHeader;
}
public override bool MustUnderstand
{
get
{
return this.innerHeader.MustUnderstand;
}
}
public override string Name
{
get
{
return this.innerHeader.Name;
}
}
public override string Namespace
{
get
{
return this.innerHeader.Namespace;
}
}
public override bool Relay
{
get
{
return this.innerHeader.Relay;
}
}
public override string Actor
{
get
{
return this.innerHeader.Actor;
}
}
protected MessageHeader InnerHeader
{
get
{
return this.innerHeader;
}
}
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
this.innerHeader.WriteStartHeader(writer, messageVersion);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
this.innerHeader.WriteHeaderContents(writer, messageVersion);
}
}
}

View File

@@ -0,0 +1,285 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Collections;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.Xml;
using System.IdentityModel.Tokens;
using System.IdentityModel.Selectors;
using System.Collections.Generic;
using System.ServiceModel.Security.Tokens;
class DerivedKeyCachingSecurityTokenSerializer : SecurityTokenSerializer
{
DerivedKeySecurityTokenCache[] cachedTokens;
WSSecureConversation secureConversation;
SecurityTokenSerializer innerTokenSerializer;
bool isInitiator;
int indexToCache = 0;
Object thisLock;
internal DerivedKeyCachingSecurityTokenSerializer(int cacheSize, bool isInitiator, WSSecureConversation secureConversation, SecurityTokenSerializer innerTokenSerializer)
: base()
{
if (innerTokenSerializer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("innerTokenSerializer");
}
if (secureConversation == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("secureConversation");
}
if (cacheSize <= 0)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("cacheSize", SR.GetString(SR.ValueMustBeGreaterThanZero)));
}
this.cachedTokens = new DerivedKeySecurityTokenCache[cacheSize];
this.isInitiator = isInitiator;
this.secureConversation = secureConversation;
this.innerTokenSerializer = innerTokenSerializer;
this.thisLock = new Object();
}
protected override bool CanReadKeyIdentifierClauseCore(XmlReader reader)
{
return this.innerTokenSerializer.CanReadKeyIdentifierClause(reader);
}
protected override bool CanReadKeyIdentifierCore(XmlReader reader)
{
return this.innerTokenSerializer.CanReadKeyIdentifier(reader);
}
protected override bool CanReadTokenCore(XmlReader reader)
{
return this.innerTokenSerializer.CanReadToken(reader);
}
protected override SecurityToken ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver)
{
XmlDictionaryReader dictionaryReader = XmlDictionaryReader.CreateDictionaryReader(reader);
if (this.secureConversation.IsAtDerivedKeyToken(dictionaryReader))
{
string id;
string derivationAlgorithm;
string label;
int length;
byte[] nonce;
int offset;
int generation;
SecurityKeyIdentifierClause tokenToDeriveIdentifier;
SecurityToken tokenToDerive;
this.secureConversation.ReadDerivedKeyTokenParameters(dictionaryReader, tokenResolver, out id, out derivationAlgorithm, out label,
out length, out nonce, out offset, out generation, out tokenToDeriveIdentifier, out tokenToDerive);
DerivedKeySecurityToken cachedToken = GetCachedToken(id, generation, offset, length, label, nonce, tokenToDerive, tokenToDeriveIdentifier, derivationAlgorithm);
if (cachedToken != null)
{
return cachedToken;
}
lock (this.thisLock)
{
cachedToken = GetCachedToken(id, generation, offset, length, label, nonce, tokenToDerive, tokenToDeriveIdentifier, derivationAlgorithm);
if (cachedToken != null)
{
return cachedToken;
}
SecurityToken result = this.secureConversation.CreateDerivedKeyToken( id, derivationAlgorithm, label, length, nonce, offset, generation, tokenToDeriveIdentifier, tokenToDerive );
DerivedKeySecurityToken newToken = result as DerivedKeySecurityToken;
if (newToken != null)
{
int pos = this.indexToCache;
if (this.indexToCache == int.MaxValue)
this.indexToCache = 0;
else
this.indexToCache = (++this.indexToCache) % this.cachedTokens.Length;
this.cachedTokens[pos] = new DerivedKeySecurityTokenCache(newToken);
}
return result;
}
}
else
{
return this.innerTokenSerializer.ReadToken(reader, tokenResolver);
}
}
protected override bool CanWriteKeyIdentifierClauseCore(SecurityKeyIdentifierClause keyIdentifierClause)
{
return this.innerTokenSerializer.CanWriteKeyIdentifierClause(keyIdentifierClause);
}
protected override bool CanWriteKeyIdentifierCore(SecurityKeyIdentifier keyIdentifier)
{
return this.innerTokenSerializer.CanWriteKeyIdentifier(keyIdentifier);
}
protected override bool CanWriteTokenCore(SecurityToken token)
{
return this.innerTokenSerializer.CanWriteToken(token);
}
protected override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore(XmlReader reader)
{
return this.innerTokenSerializer.ReadKeyIdentifierClause(reader);
}
protected override SecurityKeyIdentifier ReadKeyIdentifierCore(XmlReader reader)
{
return this.innerTokenSerializer.ReadKeyIdentifier(reader);
}
protected override void WriteKeyIdentifierClauseCore(XmlWriter writer, SecurityKeyIdentifierClause keyIdentifierClause)
{
this.innerTokenSerializer.WriteKeyIdentifierClause(writer, keyIdentifierClause);
}
protected override void WriteKeyIdentifierCore(XmlWriter writer, SecurityKeyIdentifier keyIdentifier)
{
this.innerTokenSerializer.WriteKeyIdentifier(writer, keyIdentifier);
}
protected override void WriteTokenCore(XmlWriter writer, SecurityToken token)
{
this.innerTokenSerializer.WriteToken(writer, token);
}
bool IsMatch(DerivedKeySecurityTokenCache cachedToken, string id, int generation, int offset, int length,
string label, byte[] nonce, SecurityToken tokenToDerive, string derivationAlgorithm)
{
if ((cachedToken.Generation == generation)
&& (cachedToken.Offset == offset)
&& (cachedToken.Length == length)
&& (cachedToken.Label == label)
&& (cachedToken.KeyDerivationAlgorithm == derivationAlgorithm))
{
if (!cachedToken.IsSourceKeyEqual(tokenToDerive))
{
return false;
}
// since derived key token keys are delay initialized during security processing, it may be possible
// that the cached derived key token does not have its keys initialized as yet. If so return false for
// the match so that the framework doesnt try to reference a null key.
return (CryptoHelper.IsEqual(cachedToken.Nonce, nonce) && (cachedToken.SecurityKeys != null));
}
else
{
return false;
}
}
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 && 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;
}
class DerivedKeySecurityTokenCache
{
byte[] keyToDerive;
int generation;
int offset;
int length;
string label;
string keyDerivationAlgorithm;
byte[] nonce;
ReadOnlyCollection<SecurityKey> keys;
DerivedKeySecurityToken cachedToken;
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;
}
public int Generation
{
get { return this.generation; }
}
public int Offset
{
get { return this.offset; }
}
public int Length
{
get { return this.length; }
}
public string Label
{
get { return this.label; }
}
public string KeyDerivationAlgorithm
{
get { return this.keyDerivationAlgorithm; }
}
public byte[] Nonce
{
get { return this.nonce; }
}
public ReadOnlyCollection<SecurityKey> SecurityKeys
{
get
{
// we would need to hold onto the cached token till a hit is obtained because of
// the delay initialization of derived key crypto by the security header.
lock (this)
{
if (this.keys == null)
{
ReadOnlyCollection<SecurityKey> computedKeys;
if (this.cachedToken.TryGetSecurityKeys(out computedKeys))
{
this.keys = computedKeys;
this.cachedToken = null;
}
}
}
return this.keys;
}
}
public bool IsSourceKeyEqual(SecurityToken token)
{
if (token.SecurityKeys.Count != 1)
{
return false;
}
SymmetricSecurityKey key = token.SecurityKeys[0] as SymmetricSecurityKey;
if (key == null)
{
return false;
}
return CryptoHelper.IsEqual(this.keyToDerive, key.GetSymmetricKey());
}
}
}
}

View File

@@ -0,0 +1,88 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.IdentityModel.Protocols.WSTrust;
using System.Security.Claims;
using RSTR = System.IdentityModel.Protocols.WSTrust.RequestSecurityTokenResponse;
using System.IdentityModel;
/// <summary>
/// Defines the inputs and outputs to the <see cref="WSTrustServiceContract.DispatchRequest"/> method.
/// </summary>
public class DispatchContext
{
ClaimsPrincipal principal;
string requestAction;
WSTrustMessage requestMessage;
string responseAction;
RSTR responseMessage;
SecurityTokenService securityTokenService;
string trustNamespace;
/// <summary>
/// The identity of the requestor.
/// </summary>
public ClaimsPrincipal Principal
{
get { return principal; }
set { principal = value; }
}
/// <summary>
/// The WS-Addressing action of the request message.
/// </summary>
public string RequestAction
{
get { return requestAction; }
set { requestAction = value; }
}
/// <summary>
/// The request message.
/// </summary>
public WSTrustMessage RequestMessage
{
get { return requestMessage; }
set { requestMessage = value; }
}
/// <summary>
/// The desired WS-Addressing action of the response message.
/// </summary>
public string ResponseAction
{
get { return responseAction; }
set { responseAction = value; }
}
/// <summary>
/// The response message.
/// </summary>
public RSTR ResponseMessage
{
get { return responseMessage; }
set { responseMessage = value; }
}
/// <summary>
/// The <see cref="SecurityTokenService"/> object which should process <see cref="RequestMessage"/>.
/// </summary>
public SecurityTokenService SecurityTokenService
{
get { return securityTokenService; }
set { securityTokenService = value; }
}
/// <summary>
/// The WS-Trust namespace uri defining the schema for the request and response messages.
/// </summary>
public string TrustNamespace
{
get { return trustNamespace; }
set { trustNamespace = value; }
}
}
}

View File

@@ -0,0 +1,322 @@
//----------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Channels;
sealed class DuplexSecurityProtocolFactory : SecurityProtocolFactory
{
SecurityProtocolFactory forwardProtocolFactory;
SecurityProtocolFactory reverseProtocolFactory;
bool requireSecurityOnBothDuplexDirections = true;
public DuplexSecurityProtocolFactory()
: base()
{
}
public DuplexSecurityProtocolFactory(SecurityProtocolFactory forwardProtocolFactory, SecurityProtocolFactory reverseProtocolFactory)
: this()
{
this.forwardProtocolFactory = forwardProtocolFactory;
this.reverseProtocolFactory = reverseProtocolFactory;
}
public SecurityProtocolFactory ForwardProtocolFactory
{
get
{
return this.forwardProtocolFactory;
}
set
{
ThrowIfImmutable();
this.forwardProtocolFactory = value;
}
}
SecurityProtocolFactory ProtocolFactoryForIncomingMessages
{
get
{
return this.ActAsInitiator ? this.ReverseProtocolFactory : this.ForwardProtocolFactory;
}
}
SecurityProtocolFactory ProtocolFactoryForOutgoingMessages
{
get
{
return this.ActAsInitiator ? this.ForwardProtocolFactory : this.ReverseProtocolFactory;
}
}
// If RequireSecurityOnBothDuplexDirections is set to false,
// one or both among ForwardProtocolFactory and
// ReverseProtocolFactory will be allowed to be null. The
// message directions corresponding to the null
// ProtocolFactory will have no security applied or verified.
// This mode may be used for GetPolicy message exchanges, for
// example.
public bool RequireSecurityOnBothDuplexDirections
{
get
{
return this.requireSecurityOnBothDuplexDirections;
}
set
{
ThrowIfImmutable();
this.requireSecurityOnBothDuplexDirections = value;
}
}
public SecurityProtocolFactory ReverseProtocolFactory
{
get
{
return this.reverseProtocolFactory;
}
set
{
ThrowIfImmutable();
this.reverseProtocolFactory = value;
}
}
public override bool SupportsDuplex
{
get
{
return true;
}
}
public override bool SupportsReplayDetection
{
get
{
return this.ForwardProtocolFactory != null && this.ForwardProtocolFactory.SupportsReplayDetection &&
this.ReverseProtocolFactory != null && this.ReverseProtocolFactory.SupportsReplayDetection;
}
}
public override bool SupportsRequestReply
{
get
{
return false;
}
}
public override EndpointIdentity GetIdentityOfSelf()
{
SecurityProtocolFactory factory = this.ProtocolFactoryForIncomingMessages;
if (factory != null)
{
return factory.GetIdentityOfSelf();
}
else
{
return base.GetIdentityOfSelf();
}
}
public override void OnAbort()
{
if (this.forwardProtocolFactory != null)
{
this.forwardProtocolFactory.Close(true, TimeSpan.Zero);
}
if (this.reverseProtocolFactory != null)
{
this.reverseProtocolFactory.Close(true, TimeSpan.Zero);
}
}
public override void OnClose(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
if (this.forwardProtocolFactory != null)
{
this.forwardProtocolFactory.Close(false, timeoutHelper.RemainingTime());
}
if (this.reverseProtocolFactory != null)
{
this.reverseProtocolFactory.Close(false, timeoutHelper.RemainingTime());
}
// no need to the close the base as it has no settings.
}
protected override SecurityProtocol OnCreateSecurityProtocol(EndpointAddress target, Uri via, object listenerSecurityState, TimeSpan timeout)
{
SecurityProtocolFactory outgoingFactory = this.ProtocolFactoryForOutgoingMessages;
SecurityProtocolFactory incomingFactory = this.ProtocolFactoryForIncomingMessages;
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
SecurityProtocol outgoing = outgoingFactory == null ? null : outgoingFactory.CreateSecurityProtocol(target, via, listenerSecurityState, false, timeoutHelper.RemainingTime());
SecurityProtocol incoming = incomingFactory == null ? null : incomingFactory.CreateSecurityProtocol(null, null, listenerSecurityState, false, timeoutHelper.RemainingTime());
return new DuplexSecurityProtocol(outgoing, incoming);
}
public override void OnOpen(TimeSpan timeout)
{
if (this.ForwardProtocolFactory != null && ReferenceEquals(this.ForwardProtocolFactory, this.ReverseProtocolFactory))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("ReverseProtocolFactory",
SR.GetString(SR.SameProtocolFactoryCannotBeSetForBothDuplexDirections));
}
if (this.forwardProtocolFactory != null)
{
this.forwardProtocolFactory.ListenUri = this.ListenUri;
}
if (this.reverseProtocolFactory != null)
{
this.reverseProtocolFactory.ListenUri = this.ListenUri;
}
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
Open(this.ForwardProtocolFactory, this.ActAsInitiator, "ForwardProtocolFactory", timeoutHelper.RemainingTime());
Open(this.ReverseProtocolFactory, !this.ActAsInitiator, "ReverseProtocolFactory", timeoutHelper.RemainingTime());
// no need to the open the base as it has no settings.
}
void Open(SecurityProtocolFactory factory, bool actAsInitiator, string propertyName, TimeSpan timeout)
{
if (factory != null)
{
factory.Open(actAsInitiator, timeout);
}
else if (this.RequireSecurityOnBothDuplexDirections)
{
OnPropertySettingsError(propertyName, true);
}
}
sealed class DuplexSecurityProtocol : SecurityProtocol
{
readonly SecurityProtocol outgoingProtocol;
readonly SecurityProtocol incomingProtocol;
public DuplexSecurityProtocol(SecurityProtocol outgoingProtocol, SecurityProtocol incomingProtocol)
: base(incomingProtocol.SecurityProtocolFactory, null, null)
{
this.outgoingProtocol = outgoingProtocol;
this.incomingProtocol = incomingProtocol;
}
public override void OnOpen(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
this.outgoingProtocol.Open(timeoutHelper.RemainingTime());
this.incomingProtocol.Open(timeoutHelper.RemainingTime());
}
public override void OnClose(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
this.outgoingProtocol.Close(false, timeoutHelper.RemainingTime());
this.incomingProtocol.Close(false, timeoutHelper.RemainingTime());
}
public override void OnAbort()
{
this.outgoingProtocol.Close(true, TimeSpan.Zero);
this.incomingProtocol.Close(true, TimeSpan.Zero);
}
public override IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
if (this.outgoingProtocol != null)
{
return this.outgoingProtocol.BeginSecureOutgoingMessage(message, timeout, callback, state);
}
else
{
return new CompletedAsyncResult<Message>(message, callback, state);
}
}
public override IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState,
AsyncCallback callback, object state)
{
if (this.outgoingProtocol != null)
{
return this.outgoingProtocol.BeginSecureOutgoingMessage(message, timeout, correlationState, callback, state);
}
else
{
return new CompletedAsyncResult<Message, SecurityProtocolCorrelationState>(message, null, callback, state);
}
}
public override void EndSecureOutgoingMessage(IAsyncResult result, out Message message)
{
if (this.outgoingProtocol != null)
{
this.outgoingProtocol.EndSecureOutgoingMessage(result, out message);
}
else
{
message = CompletedAsyncResult<Message>.End(result);
}
}
public override void EndSecureOutgoingMessage(IAsyncResult result,
out Message message, out SecurityProtocolCorrelationState newCorrelationState)
{
if (this.outgoingProtocol != null)
{
this.outgoingProtocol.EndSecureOutgoingMessage(result, out message, out newCorrelationState);
}
else
{
message = CompletedAsyncResult<Message, SecurityProtocolCorrelationState>.End(result, out newCorrelationState);
}
}
public override void SecureOutgoingMessage(ref Message message, TimeSpan timeout)
{
if (this.outgoingProtocol != null)
{
this.outgoingProtocol.SecureOutgoingMessage(ref message, timeout);
}
}
public override SecurityProtocolCorrelationState SecureOutgoingMessage(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
{
if (this.outgoingProtocol != null)
{
return this.outgoingProtocol.SecureOutgoingMessage(ref message, timeout, correlationState);
}
else
{
return null;
}
}
public override void VerifyIncomingMessage(ref Message message, TimeSpan timeout)
{
if (this.incomingProtocol != null)
{
this.incomingProtocol.VerifyIncomingMessage(ref message, timeout);
}
}
public override SecurityProtocolCorrelationState VerifyIncomingMessage(ref Message message, TimeSpan timeout,
params SecurityProtocolCorrelationState[] correlationStates)
{
if (this.incomingProtocol != null)
{
return this.incomingProtocol.VerifyIncomingMessage(ref message, timeout, correlationStates);
}
else
{
return null;
}
}
}
}
}

View File

@@ -0,0 +1,103 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Security.Cryptography;
using System.ServiceModel.Channels;
using System.Xml;
class EncryptedData : EncryptedType
{
internal static readonly XmlDictionaryString ElementName = XD.XmlEncryptionDictionary.EncryptedData;
internal static readonly string ElementType = XmlEncryptionStrings.ElementType;
internal static readonly string ContentType = XmlEncryptionStrings.ContentType;
SymmetricAlgorithm algorithm;
byte[] decryptedBuffer;
ArraySegment<byte> buffer;
byte[] iv;
byte[] cipherText;
protected override XmlDictionaryString OpeningElementName
{
get { return ElementName; }
}
void EnsureDecryptionSet()
{
if (this.State == EncryptionState.DecryptionSetup)
{
SetPlainText();
}
else if (this.State != EncryptionState.Decrypted)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.BadEncryptionState)));
}
}
protected override void ForceEncryption()
{
CryptoHelper.GenerateIVAndEncrypt(this.algorithm, this.buffer, out this.iv, out this.cipherText);
this.State = EncryptionState.Encrypted;
this.buffer = new ArraySegment<byte>(CryptoHelper.EmptyBuffer);
}
public byte[] GetDecryptedBuffer()
{
EnsureDecryptionSet();
return this.decryptedBuffer;
}
protected override void ReadCipherData(XmlDictionaryReader reader)
{
this.cipherText = reader.ReadContentAsBase64();
}
protected override void ReadCipherData(XmlDictionaryReader reader, long maxBufferSize)
{
this.cipherText = SecurityUtils.ReadContentAsBase64(reader, maxBufferSize);
}
void SetPlainText()
{
this.decryptedBuffer = CryptoHelper.ExtractIVAndDecrypt(this.algorithm, this.cipherText, 0, this.cipherText.Length);
this.State = EncryptionState.Decrypted;
}
public void SetUpDecryption(SymmetricAlgorithm algorithm)
{
if (this.State != EncryptionState.Read)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.BadEncryptionState)));
}
if (algorithm == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("algorithm");
}
this.algorithm = algorithm;
this.State = EncryptionState.DecryptionSetup;
}
public void SetUpEncryption(SymmetricAlgorithm algorithm, ArraySegment<byte> buffer)
{
if (this.State != EncryptionState.New)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.BadEncryptionState)));
}
if (algorithm == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("algorithm");
}
this.algorithm = algorithm;
this.buffer = buffer;
this.State = EncryptionState.EncryptionSetup;
}
protected override void WriteCipherData(XmlDictionaryWriter writer)
{
writer.WriteBase64(this.iv, 0, this.iv.Length);
writer.WriteBase64(this.cipherText, 0, this.cipherText.Length);
}
}
}

Some files were not shown because too many files have changed in this diff Show More