diff options
Diffstat (limited to 'src')
20 files changed, 545 insertions, 306 deletions
diff --git a/src/DotNetOpenAuth.Test/Mocks/TestBaseMessage.cs b/src/DotNetOpenAuth.Test/Mocks/TestBaseMessage.cs index ef0693c..bd17dd6 100644 --- a/src/DotNetOpenAuth.Test/Mocks/TestBaseMessage.cs +++ b/src/DotNetOpenAuth.Test/Mocks/TestBaseMessage.cs @@ -43,6 +43,8 @@ namespace DotNetOpenAuth.Test.Mocks { get { return this.extraData; } } + bool IProtocolMessage.Incoming { get; set; } + internal string PrivatePropertyAccessor { get { return this.PrivateProperty; } set { this.PrivateProperty = value; } diff --git a/src/DotNetOpenAuth.Test/Mocks/TestMessage.cs b/src/DotNetOpenAuth.Test/Mocks/TestMessage.cs index 301e70d..55e44ba 100644 --- a/src/DotNetOpenAuth.Test/Mocks/TestMessage.cs +++ b/src/DotNetOpenAuth.Test/Mocks/TestMessage.cs @@ -52,6 +52,8 @@ namespace DotNetOpenAuth.Test.Mocks { get { return this.extraData; } } + bool IProtocolMessage.Incoming { get; set; } + void IProtocolMessage.EnsureValidMessage() { if (this.EmptyMember != null || this.Age < 0) { throw new ProtocolException(); diff --git a/src/DotNetOpenAuth.Test/OpenId/OpenIdScenarioTests.cs b/src/DotNetOpenAuth.Test/OpenId/OpenIdScenarioTests.cs index 62982bd..f56f576 100644 --- a/src/DotNetOpenAuth.Test/OpenId/OpenIdScenarioTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/OpenIdScenarioTests.cs @@ -22,12 +22,11 @@ namespace DotNetOpenAuth.Test.OpenId { public void AssociateDiffieHellmanMessages() { Association rpAssociation = null, opAssociation; AssociateDiffieHellmanResponse associateResponse = null; - var opDescription = new ProviderEndpointDescription(new Uri("http://host"), Protocol); + var opDescription = new ProviderEndpointDescription(new Uri("http://host"), this.Protocol); OpenIdCoordinator coordinator = new OpenIdCoordinator( rp => { rpAssociation = rp.GetAssociation(opDescription); Assert.IsNotNull(rpAssociation); - Assert.IsFalse(MessagingUtilities.AreEquivalent(associateResponse.EncodedMacKey, rpAssociation.SecretKey), "Key should have been encrypted."); }, op => { op.AutoRespond(); @@ -43,6 +42,44 @@ namespace DotNetOpenAuth.Test.OpenId { Assert.AreSame(rpAssociation, coordinator.RelyingParty.AssociationStore.GetAssociation(opDescription.Endpoint, rpAssociation.Handle)); opAssociation = coordinator.Provider.AssociationStore.GetAssociation(AssociationRelyingPartyType.Smart, rpAssociation.Handle); Assert.IsNotNull(opAssociation, "The Provider should have stored the association."); + + Assert.AreEqual(opAssociation.Handle, rpAssociation.Handle); + Assert.IsFalse(MessagingUtilities.AreEquivalent(associateResponse.EncodedMacKey, rpAssociation.SecretKey), "Key should have been encrypted."); + Assert.IsTrue(Math.Abs(opAssociation.SecondsTillExpiration - rpAssociation.SecondsTillExpiration) < 60); + Assert.IsTrue(MessagingUtilities.AreEquivalent(opAssociation.SecretKey, rpAssociation.SecretKey)); + } + + [TestMethod] + public void AssociateUnencryptedMessages() { + Association rpAssociation = null, opAssociation; + AssociateUnencryptedResponse associateResponse = null; + bool unencryptedRequestSent = false; + var opDescription = new ProviderEndpointDescription(new Uri("https://host"), this.Protocol); + OpenIdCoordinator coordinator = new OpenIdCoordinator( + rp => { + rpAssociation = rp.GetAssociation(opDescription); + Assert.IsNotNull(rpAssociation); + }, + op => { + op.AutoRespond(); + }); + coordinator.IncomingMessageFilter = message => { + var associateResponseMessage = message as AssociateUnencryptedResponse; + if (associateResponseMessage != null) { + // capture this message as it comes into the RP so we can analyze it later + associateResponse = associateResponseMessage; + } + }; + coordinator.OutgoingMessageFilter = message => { + // we want to check that the RP is sending a request that doesn't require DH + unencryptedRequestSent |= message is AssociateUnencryptedRequest; + }; + coordinator.Run(); + Assert.AreSame(rpAssociation, coordinator.RelyingParty.AssociationStore.GetAssociation(opDescription.Endpoint, rpAssociation.Handle)); + opAssociation = coordinator.Provider.AssociationStore.GetAssociation(AssociationRelyingPartyType.Smart, rpAssociation.Handle); + Assert.IsNotNull(opAssociation, "The Provider should have stored the association."); + + Assert.IsTrue(unencryptedRequestSent, "An unencrypted association request should have been used since HTTPS was the transport."); Assert.AreEqual(opAssociation.Handle, rpAssociation.Handle); Assert.IsTrue(Math.Abs(opAssociation.SecondsTillExpiration - rpAssociation.SecondsTillExpiration) < 60); Assert.IsTrue(MessagingUtilities.AreEquivalent(opAssociation.SecretKey, rpAssociation.SecretKey)); diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index 8e94b2d..452dbf6 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -1,244 +1,245 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>DotNetOpenAuth</RootNamespace>
- <AssemblyName>DotNetOpenAuth</AssemblyName>
- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>..\..\bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <DocumentationFile>..\..\bin\Debug\DotNetOpenAuth.xml</DocumentationFile>
- <RunCodeAnalysis>false</RunCodeAnalysis>
- <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>..\..\bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <DocumentationFile>..\..\bin\debug\DotNetOpenAuth.xml</DocumentationFile>
- <RunCodeAnalysis>true</RunCodeAnalysis>
- <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Sign)' == 'true' ">
- <SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile>
- <DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\lib\log4net.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.configuration" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.ServiceModel">
- <RequiredTargetFramework>3.0</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Web" />
- <Reference Include="System.XML" />
- <Reference Include="System.Xml.Linq">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Configuration\ProviderSection.cs" />
- <Compile Include="Configuration\ProviderSecuritySettingsElement.cs" />
- <Compile Include="Configuration\RelyingPartySection.cs" />
- <Compile Include="Configuration\RelyingPartySecuritySettingsElement.cs" />
- <Compile Include="Configuration\TypeConfigurationElement.cs" />
- <Compile Include="Configuration\UntrustedWebRequestSection.cs" />
- <Compile Include="Configuration\HostNameOrRegexCollection.cs" />
- <Compile Include="Configuration\HostNameElement.cs" />
- <Compile Include="Messaging\EmptyDictionary.cs" />
- <Compile Include="Messaging\EmptyEnumerator.cs" />
- <Compile Include="Messaging\EmptyList.cs" />
- <Compile Include="Messaging\ErrorUtilities.cs" />
- <Compile Include="Messaging\Reflection\IMessagePartEncoder.cs" />
- <Compile Include="OAuth\ChannelElements\OAuthConsumerMessageTypeProvider.cs" />
- <Compile Include="OAuth\ChannelElements\ITokenGenerator.cs" />
- <Compile Include="OAuth\ChannelElements\ITokenManager.cs" />
- <Compile Include="OAuth\ChannelElements\OAuthHttpMethodBindingElement.cs" />
- <Compile Include="OAuth\ChannelElements\PlaintextSigningBindingElement.cs" />
- <Compile Include="OAuth\ChannelElements\HmacSha1SigningBindingElement.cs" />
- <Compile Include="OAuth\ChannelElements\SigningBindingElementChain.cs" />
- <Compile Include="OAuth\ChannelElements\StandardTokenGenerator.cs" />
- <Compile Include="OAuth\ChannelElements\TokenType.cs" />
- <Compile Include="OAuth\ConsumerBase.cs" />
- <Compile Include="OAuth\DesktopConsumer.cs" />
- <Compile Include="GlobalSuppressions.cs" />
- <Compile Include="OAuth\Messages\ITokenSecretContainingMessage.cs" />
- <Compile Include="Messaging\ChannelEventArgs.cs" />
- <Compile Include="Messaging\ITamperProtectionChannelBindingElement.cs" />
- <Compile Include="OAuth\OAuthStrings.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>OAuthStrings.resx</DependentUpon>
- </Compile>
- <Compile Include="OAuth\ServiceProviderDescription.cs" />
- <Compile Include="OAuth\Messages\ITokenContainingMessage.cs" />
- <Compile Include="OAuth\Messages\SignedMessageBase.cs" />
- <Compile Include="Messaging\Bindings\NonceMemoryStore.cs" />
- <Compile Include="OAuth\ChannelElements\SigningBindingElementBase.cs" />
- <Compile Include="OAuth\WebConsumer.cs" />
- <Compile Include="Messaging\IWebRequestHandler.cs" />
- <Compile Include="OAuth\ChannelElements\ITamperResistantOAuthMessage.cs" />
- <Compile Include="OAuth\Messages\MessageBase.cs" />
- <Compile Include="OAuth\Messages\AuthorizedTokenRequest.cs" />
- <Compile Include="Messaging\Bindings\INonceStore.cs" />
- <Compile Include="Messaging\Bindings\StandardReplayProtectionBindingElement.cs" />
- <Compile Include="Messaging\MessagePartAttribute.cs" />
- <Compile Include="Messaging\MessageProtections.cs" />
- <Compile Include="Messaging\IChannelBindingElement.cs" />
- <Compile Include="Messaging\Bindings\ReplayedMessageException.cs" />
- <Compile Include="Messaging\Bindings\ExpiredMessageException.cs" />
- <Compile Include="Messaging\Bindings\InvalidSignatureException.cs" />
- <Compile Include="Messaging\Bindings\IReplayProtectedProtocolMessage.cs" />
- <Compile Include="Messaging\Bindings\IExpiringProtocolMessage.cs" />
- <Compile Include="OAuth\Messages\AccessProtectedResourceRequest.cs" />
- <Compile Include="OAuth\Messages\AuthorizedTokenResponse.cs" />
- <Compile Include="OAuth\Messages\UserAuthorizationResponse.cs" />
- <Compile Include="OAuth\Messages\UserAuthorizationRequest.cs" />
- <Compile Include="OAuth\Messages\UnauthorizedTokenResponse.cs" />
- <Compile Include="Messaging\Channel.cs" />
- <Compile Include="Messaging\HttpRequestInfo.cs" />
- <Compile Include="Messaging\IDirectedProtocolMessage.cs" />
- <Compile Include="Messaging\IMessageTypeProvider.cs" />
- <Compile Include="Messaging\ITamperResistantProtocolMessage.cs" />
- <Compile Include="Messaging\MessageSerializer.cs" />
- <Compile Include="Messaging\MessagingStrings.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>MessagingStrings.resx</DependentUpon>
- </Compile>
- <Compile Include="Messaging\MessagingUtilities.cs" />
- <Compile Include="Messaging\Bindings\StandardExpirationBindingElement.cs" />
- <Compile Include="Messaging\Reflection\ValueMapping.cs" />
- <Compile Include="Messaging\Reflection\MessageDescription.cs" />
- <Compile Include="Messaging\Reflection\MessageDictionary.cs" />
- <Compile Include="Messaging\Reflection\MessagePart.cs" />
- <Compile Include="Messaging\UnprotectedMessageException.cs" />
- <Compile Include="OAuth\ChannelElements\OAuthChannel.cs" />
- <Compile Include="Messaging\Response.cs" />
- <Compile Include="Messaging\IProtocolMessage.cs" />
- <Compile Include="Logger.cs" />
- <Compile Include="Loggers\ILog.cs" />
- <Compile Include="Loggers\Log4NetLogger.cs" />
- <Compile Include="Loggers\NoOpLogger.cs" />
- <Compile Include="Loggers\TraceLogger.cs" />
- <Compile Include="Messaging\HttpDeliveryMethods.cs" />
- <Compile Include="Messaging\MessageTransport.cs" />
- <Compile Include="OAuth\ChannelElements\OAuthServiceProviderMessageTypeProvider.cs" />
- <Compile Include="Messaging\ProtocolException.cs" />
- <Compile Include="OpenId\Association.cs" />
- <Compile Include="OpenId\AssociationMemoryStore.cs" />
- <Compile Include="OpenId\Associations.cs" />
- <Compile Include="OpenId\ChannelElements\ITamperResistantOpenIdMessage.cs" />
- <Compile Include="OpenId\ChannelElements\SigningBindingElement.cs" />
- <Compile Include="OpenId\ChannelElements\KeyValueFormEncoding.cs" />
- <Compile Include="OpenId\ChannelElements\OpenIdChannel.cs" />
- <Compile Include="OpenId\ChannelElements\OpenIdMessageTypeProvider.cs" />
- <Compile Include="OpenId\Configuration.cs" />
- <Compile Include="OpenId\RelyingPartyDescription.cs" />
- <Compile Include="OpenId\DiffieHellmanUtilities.cs" />
- <Compile Include="OpenId\DiffieHellman\DHKeyGeneration.cs" />
- <Compile Include="OpenId\DiffieHellman\DHParameters.cs" />
- <Compile Include="OpenId\DiffieHellman\DiffieHellman.cs" />
- <Compile Include="OpenId\DiffieHellman\DiffieHellmanManaged.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\BigInteger.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\ConfidenceFactor.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\NextPrimeFinder.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\PrimalityTests.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\PrimeGeneratorBase.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\SequentialSearchPrimeGeneratorBase.cs" />
- <Compile Include="OpenId\HmacShaAssociation.cs" />
- <Compile Include="OpenId\IAssociationStore.cs" />
- <Compile Include="OpenId\Messages\AssociateUnencryptedRequest.cs" />
- <Compile Include="OpenId\OpenIdProvider.cs" />
- <Compile Include="OpenId\Messages\AssociateDiffieHellmanRequest.cs" />
- <Compile Include="OpenId\Messages\AssociateDiffieHellmanResponse.cs" />
- <Compile Include="OpenId\Messages\AssociateRequest.cs" />
- <Compile Include="OpenId\Messages\AssociateSuccessfulResponse.cs" />
- <Compile Include="OpenId\Messages\AssociateUnencryptedResponse.cs" />
- <Compile Include="OpenId\Messages\AssociateUnsuccessfulResponse.cs" />
- <Compile Include="OpenId\Messages\IndirectErrorResponse.cs" />
- <Compile Include="OpenId\Messages\DirectErrorResponse.cs" />
- <Compile Include="OpenId\Messages\RequestBase.cs" />
- <Compile Include="OpenId\Messages\DirectResponseBase.cs" />
- <Compile Include="OpenId\OpenIdRelyingParty.cs" />
- <Compile Include="OpenId\OpenIdStrings.Designer.cs">
- <DependentUpon>OpenIdStrings.resx</DependentUpon>
- <DesignTime>True</DesignTime>
- <AutoGen>True</AutoGen>
- </Compile>
- <Compile Include="OpenId\Protocol.cs" />
- <Compile Include="OpenId\ProviderDescription.cs" />
- <Compile Include="OpenId\Provider\ProviderSecuritySettings.cs" />
- <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettings.cs" />
- <Compile Include="OpenId\SecuritySettings.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="OAuth\Messages\UnauthorizedTokenRequest.cs" />
- <Compile Include="OAuth\ChannelElements\RsaSha1SigningBindingElement.cs" />
- <Compile Include="Messaging\StandardWebRequestHandler.cs" />
- <Compile Include="Messaging\MessageReceivingEndpoint.cs" />
- <Compile Include="Util.cs" />
- <Compile Include="OAuth\Protocol.cs" />
- <Compile Include="OAuth\ServiceProvider.cs" />
- <Compile Include="Strings.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>Strings.resx</DependentUpon>
- </Compile>
- <Compile Include="UriUtil.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="ClassDiagram.cd" />
- <None Include="OAuth\Messages\OAuth Messages.cd" />
- <None Include="Messaging\Bindings\Bindings.cd" />
- <None Include="Messaging\Exceptions.cd" />
- <None Include="Messaging\Messaging.cd" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Messaging\MessagingStrings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>MessagingStrings.Designer.cs</LastGenOutput>
- </EmbeddedResource>
- <EmbeddedResource Include="OAuth\OAuthStrings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>OAuthStrings.Designer.cs</LastGenOutput>
- </EmbeddedResource>
- <EmbeddedResource Include="OpenId\OpenIdStrings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>OpenIdStrings.Designer.cs</LastGenOutput>
- </EmbeddedResource>
- <EmbeddedResource Include="Strings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>Strings.Designer.cs</LastGenOutput>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="..\..\tools\DotNetOpenAuth.Versioning.targets" />
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.30729</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>DotNetOpenAuth</RootNamespace> + <AssemblyName>DotNetOpenAuth</AssemblyName> + <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\..\bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <AllowUnsafeBlocks>false</AllowUnsafeBlocks> + <DocumentationFile>..\..\bin\Debug\DotNetOpenAuth.xml</DocumentationFile> + <RunCodeAnalysis>false</RunCodeAnalysis> + <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>..\..\bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <AllowUnsafeBlocks>false</AllowUnsafeBlocks> + <DocumentationFile>..\..\bin\debug\DotNetOpenAuth.xml</DocumentationFile> + <RunCodeAnalysis>true</RunCodeAnalysis> + <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules> + </PropertyGroup> + <PropertyGroup Condition=" '$(Sign)' == 'true' "> + <SignAssembly>true</SignAssembly> + <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile> + <DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants> + </PropertyGroup> + <ItemGroup> + <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\..\lib\log4net.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.configuration" /> + <Reference Include="System.Core"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data" /> + <Reference Include="System.ServiceModel"> + <RequiredTargetFramework>3.0</RequiredTargetFramework> + </Reference> + <Reference Include="System.Web" /> + <Reference Include="System.XML" /> + <Reference Include="System.Xml.Linq"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + </ItemGroup> + <ItemGroup> + <Compile Include="Configuration\ProviderSection.cs" /> + <Compile Include="Configuration\ProviderSecuritySettingsElement.cs" /> + <Compile Include="Configuration\RelyingPartySection.cs" /> + <Compile Include="Configuration\RelyingPartySecuritySettingsElement.cs" /> + <Compile Include="Configuration\TypeConfigurationElement.cs" /> + <Compile Include="Configuration\UntrustedWebRequestSection.cs" /> + <Compile Include="Configuration\HostNameOrRegexCollection.cs" /> + <Compile Include="Configuration\HostNameElement.cs" /> + <Compile Include="Messaging\EmptyDictionary.cs" /> + <Compile Include="Messaging\EmptyEnumerator.cs" /> + <Compile Include="Messaging\EmptyList.cs" /> + <Compile Include="Messaging\ErrorUtilities.cs" /> + <Compile Include="Messaging\InternalErrorException.cs" /> + <Compile Include="Messaging\Reflection\IMessagePartEncoder.cs" /> + <Compile Include="OAuth\ChannelElements\OAuthConsumerMessageTypeProvider.cs" /> + <Compile Include="OAuth\ChannelElements\ITokenGenerator.cs" /> + <Compile Include="OAuth\ChannelElements\ITokenManager.cs" /> + <Compile Include="OAuth\ChannelElements\OAuthHttpMethodBindingElement.cs" /> + <Compile Include="OAuth\ChannelElements\PlaintextSigningBindingElement.cs" /> + <Compile Include="OAuth\ChannelElements\HmacSha1SigningBindingElement.cs" /> + <Compile Include="OAuth\ChannelElements\SigningBindingElementChain.cs" /> + <Compile Include="OAuth\ChannelElements\StandardTokenGenerator.cs" /> + <Compile Include="OAuth\ChannelElements\TokenType.cs" /> + <Compile Include="OAuth\ConsumerBase.cs" /> + <Compile Include="OAuth\DesktopConsumer.cs" /> + <Compile Include="GlobalSuppressions.cs" /> + <Compile Include="OAuth\Messages\ITokenSecretContainingMessage.cs" /> + <Compile Include="Messaging\ChannelEventArgs.cs" /> + <Compile Include="Messaging\ITamperProtectionChannelBindingElement.cs" /> + <Compile Include="OAuth\OAuthStrings.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>OAuthStrings.resx</DependentUpon> + </Compile> + <Compile Include="OAuth\ServiceProviderDescription.cs" /> + <Compile Include="OAuth\Messages\ITokenContainingMessage.cs" /> + <Compile Include="OAuth\Messages\SignedMessageBase.cs" /> + <Compile Include="Messaging\Bindings\NonceMemoryStore.cs" /> + <Compile Include="OAuth\ChannelElements\SigningBindingElementBase.cs" /> + <Compile Include="OAuth\WebConsumer.cs" /> + <Compile Include="Messaging\IWebRequestHandler.cs" /> + <Compile Include="OAuth\ChannelElements\ITamperResistantOAuthMessage.cs" /> + <Compile Include="OAuth\Messages\MessageBase.cs" /> + <Compile Include="OAuth\Messages\AuthorizedTokenRequest.cs" /> + <Compile Include="Messaging\Bindings\INonceStore.cs" /> + <Compile Include="Messaging\Bindings\StandardReplayProtectionBindingElement.cs" /> + <Compile Include="Messaging\MessagePartAttribute.cs" /> + <Compile Include="Messaging\MessageProtections.cs" /> + <Compile Include="Messaging\IChannelBindingElement.cs" /> + <Compile Include="Messaging\Bindings\ReplayedMessageException.cs" /> + <Compile Include="Messaging\Bindings\ExpiredMessageException.cs" /> + <Compile Include="Messaging\Bindings\InvalidSignatureException.cs" /> + <Compile Include="Messaging\Bindings\IReplayProtectedProtocolMessage.cs" /> + <Compile Include="Messaging\Bindings\IExpiringProtocolMessage.cs" /> + <Compile Include="OAuth\Messages\AccessProtectedResourceRequest.cs" /> + <Compile Include="OAuth\Messages\AuthorizedTokenResponse.cs" /> + <Compile Include="OAuth\Messages\UserAuthorizationResponse.cs" /> + <Compile Include="OAuth\Messages\UserAuthorizationRequest.cs" /> + <Compile Include="OAuth\Messages\UnauthorizedTokenResponse.cs" /> + <Compile Include="Messaging\Channel.cs" /> + <Compile Include="Messaging\HttpRequestInfo.cs" /> + <Compile Include="Messaging\IDirectedProtocolMessage.cs" /> + <Compile Include="Messaging\IMessageTypeProvider.cs" /> + <Compile Include="Messaging\ITamperResistantProtocolMessage.cs" /> + <Compile Include="Messaging\MessageSerializer.cs" /> + <Compile Include="Messaging\MessagingStrings.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>MessagingStrings.resx</DependentUpon> + </Compile> + <Compile Include="Messaging\MessagingUtilities.cs" /> + <Compile Include="Messaging\Bindings\StandardExpirationBindingElement.cs" /> + <Compile Include="Messaging\Reflection\ValueMapping.cs" /> + <Compile Include="Messaging\Reflection\MessageDescription.cs" /> + <Compile Include="Messaging\Reflection\MessageDictionary.cs" /> + <Compile Include="Messaging\Reflection\MessagePart.cs" /> + <Compile Include="Messaging\UnprotectedMessageException.cs" /> + <Compile Include="OAuth\ChannelElements\OAuthChannel.cs" /> + <Compile Include="Messaging\Response.cs" /> + <Compile Include="Messaging\IProtocolMessage.cs" /> + <Compile Include="Logger.cs" /> + <Compile Include="Loggers\ILog.cs" /> + <Compile Include="Loggers\Log4NetLogger.cs" /> + <Compile Include="Loggers\NoOpLogger.cs" /> + <Compile Include="Loggers\TraceLogger.cs" /> + <Compile Include="Messaging\HttpDeliveryMethods.cs" /> + <Compile Include="Messaging\MessageTransport.cs" /> + <Compile Include="OAuth\ChannelElements\OAuthServiceProviderMessageTypeProvider.cs" /> + <Compile Include="Messaging\ProtocolException.cs" /> + <Compile Include="OpenId\Association.cs" /> + <Compile Include="OpenId\AssociationMemoryStore.cs" /> + <Compile Include="OpenId\Associations.cs" /> + <Compile Include="OpenId\ChannelElements\ITamperResistantOpenIdMessage.cs" /> + <Compile Include="OpenId\ChannelElements\SigningBindingElement.cs" /> + <Compile Include="OpenId\ChannelElements\KeyValueFormEncoding.cs" /> + <Compile Include="OpenId\ChannelElements\OpenIdChannel.cs" /> + <Compile Include="OpenId\ChannelElements\OpenIdMessageTypeProvider.cs" /> + <Compile Include="OpenId\Configuration.cs" /> + <Compile Include="OpenId\RelyingPartyDescription.cs" /> + <Compile Include="OpenId\DiffieHellmanUtilities.cs" /> + <Compile Include="OpenId\DiffieHellman\DHKeyGeneration.cs" /> + <Compile Include="OpenId\DiffieHellman\DHParameters.cs" /> + <Compile Include="OpenId\DiffieHellman\DiffieHellman.cs" /> + <Compile Include="OpenId\DiffieHellman\DiffieHellmanManaged.cs" /> + <Compile Include="OpenId\DiffieHellman\mono\BigInteger.cs" /> + <Compile Include="OpenId\DiffieHellman\mono\ConfidenceFactor.cs" /> + <Compile Include="OpenId\DiffieHellman\mono\NextPrimeFinder.cs" /> + <Compile Include="OpenId\DiffieHellman\mono\PrimalityTests.cs" /> + <Compile Include="OpenId\DiffieHellman\mono\PrimeGeneratorBase.cs" /> + <Compile Include="OpenId\DiffieHellman\mono\SequentialSearchPrimeGeneratorBase.cs" /> + <Compile Include="OpenId\HmacShaAssociation.cs" /> + <Compile Include="OpenId\IAssociationStore.cs" /> + <Compile Include="OpenId\Messages\AssociateUnencryptedRequest.cs" /> + <Compile Include="OpenId\OpenIdProvider.cs" /> + <Compile Include="OpenId\Messages\AssociateDiffieHellmanRequest.cs" /> + <Compile Include="OpenId\Messages\AssociateDiffieHellmanResponse.cs" /> + <Compile Include="OpenId\Messages\AssociateRequest.cs" /> + <Compile Include="OpenId\Messages\AssociateSuccessfulResponse.cs" /> + <Compile Include="OpenId\Messages\AssociateUnencryptedResponse.cs" /> + <Compile Include="OpenId\Messages\AssociateUnsuccessfulResponse.cs" /> + <Compile Include="OpenId\Messages\IndirectErrorResponse.cs" /> + <Compile Include="OpenId\Messages\DirectErrorResponse.cs" /> + <Compile Include="OpenId\Messages\RequestBase.cs" /> + <Compile Include="OpenId\Messages\DirectResponseBase.cs" /> + <Compile Include="OpenId\OpenIdRelyingParty.cs" /> + <Compile Include="OpenId\OpenIdStrings.Designer.cs"> + <DependentUpon>OpenIdStrings.resx</DependentUpon> + <DesignTime>True</DesignTime> + <AutoGen>True</AutoGen> + </Compile> + <Compile Include="OpenId\Protocol.cs" /> + <Compile Include="OpenId\ProviderDescription.cs" /> + <Compile Include="OpenId\Provider\ProviderSecuritySettings.cs" /> + <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettings.cs" /> + <Compile Include="OpenId\SecuritySettings.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="OAuth\Messages\UnauthorizedTokenRequest.cs" /> + <Compile Include="OAuth\ChannelElements\RsaSha1SigningBindingElement.cs" /> + <Compile Include="Messaging\StandardWebRequestHandler.cs" /> + <Compile Include="Messaging\MessageReceivingEndpoint.cs" /> + <Compile Include="Util.cs" /> + <Compile Include="OAuth\Protocol.cs" /> + <Compile Include="OAuth\ServiceProvider.cs" /> + <Compile Include="Strings.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Strings.resx</DependentUpon> + </Compile> + <Compile Include="UriUtil.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="ClassDiagram.cd" /> + <None Include="OAuth\Messages\OAuth Messages.cd" /> + <None Include="Messaging\Bindings\Bindings.cd" /> + <None Include="Messaging\Exceptions.cd" /> + <None Include="Messaging\Messaging.cd" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Messaging\MessagingStrings.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>MessagingStrings.Designer.cs</LastGenOutput> + </EmbeddedResource> + <EmbeddedResource Include="OAuth\OAuthStrings.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>OAuthStrings.Designer.cs</LastGenOutput> + </EmbeddedResource> + <EmbeddedResource Include="OpenId\OpenIdStrings.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>OpenIdStrings.Designer.cs</LastGenOutput> + </EmbeddedResource> + <EmbeddedResource Include="Strings.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Strings.Designer.cs</LastGenOutput> + <SubType>Designer</SubType> + </EmbeddedResource> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="..\..\tools\DotNetOpenAuth.Versioning.targets" /> </Project>
\ No newline at end of file diff --git a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs index 0ae766d..5e89a77 100644 --- a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs @@ -24,6 +24,17 @@ namespace DotNetOpenAuth.Messaging { } /// <summary> + /// Checks a condition and throws an internal error exception if it evaluates to false. + /// </summary> + /// <param name="condition">The condition to check.</param> + /// <param name="errorMessage">The message to include in the exception, if created.</param> + internal static void VerifyInternal(bool condition, string errorMessage) { + if (!condition) { + throw new InternalErrorException(errorMessage); + } + } + + /// <summary> /// Throws a <see cref="ProtocolException"/> if some <paramref name="condition"/> evaluates to false. /// </summary> /// <param name="condition">True to do nothing; false to throw the exception.</param> diff --git a/src/DotNetOpenAuth/Messaging/IProtocolMessage.cs b/src/DotNetOpenAuth/Messaging/IProtocolMessage.cs index 1dc20ba..9e3be80 100644 --- a/src/DotNetOpenAuth/Messaging/IProtocolMessage.cs +++ b/src/DotNetOpenAuth/Messaging/IProtocolMessage.cs @@ -38,6 +38,15 @@ namespace DotNetOpenAuth.Messaging { IDictionary<string, string> ExtraData { get; } /// <summary> + /// Gets or sets a value indicating whether this message was deserialized as an incoming message. + /// </summary> + /// <remarks> + /// In message type implementations, this property should default to false and will be set + /// to true by the messaging system when the message is deserialized as an incoming message. + /// </remarks> + bool Incoming { get; set; } + + /// <summary> /// Checks the message state for conformity to the protocol specification /// and throws an exception if the message is invalid. /// </summary> diff --git a/src/DotNetOpenAuth/Messaging/InternalErrorException.cs b/src/DotNetOpenAuth/Messaging/InternalErrorException.cs new file mode 100644 index 0000000..12147f5 --- /dev/null +++ b/src/DotNetOpenAuth/Messaging/InternalErrorException.cs @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------- +// <copyright file="InternalErrorException.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Messaging { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + /// <summary> + /// An internal exception to throw if an internal error within the library requires + /// an abort of the operation. + /// </summary> + /// <remarks> + /// This exception is internal to prevent clients of the library from catching what is + /// really an unexpected, potentially unrecoverable exception. + /// </remarks> + [global::System.Serializable] + internal class InternalErrorException : Exception { + /// <summary> + /// Initializes a new instance of the <see cref="InternalErrorException"/> class. + /// </summary> + public InternalErrorException() { } + + /// <summary> + /// Initializes a new instance of the <see cref="InternalErrorException"/> class. + /// </summary> + /// <param name="message">The message.</param> + public InternalErrorException(string message) : base(message) { } + + /// <summary> + /// Initializes a new instance of the <see cref="InternalErrorException"/> class. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="inner">The inner exception.</param> + public InternalErrorException(string message, Exception inner) : base(message, inner) { } + + /// <summary> + /// Initializes a new instance of the <see cref="InternalErrorException"/> class. + /// </summary> + /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param> + /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param> + /// <exception cref="T:System.ArgumentNullException"> + /// The <paramref name="info"/> parameter is null. + /// </exception> + /// <exception cref="T:System.Runtime.Serialization.SerializationException"> + /// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0). + /// </exception> + protected InternalErrorException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) + : base(info, context) { } + } +} diff --git a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs index f3ce70f..5e86949 100644 --- a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs +++ b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs @@ -135,6 +135,7 @@ namespace DotNetOpenAuth.Messaging { result = (IProtocolMessage)Activator.CreateInstance(this.messageType, true); } + result.Incoming = true; return result; } } diff --git a/src/DotNetOpenAuth/Messaging/ProtocolException.cs b/src/DotNetOpenAuth/Messaging/ProtocolException.cs index 1b1557e..e4a0a44 100644 --- a/src/DotNetOpenAuth/Messaging/ProtocolException.cs +++ b/src/DotNetOpenAuth/Messaging/ProtocolException.cs @@ -129,6 +129,11 @@ namespace DotNetOpenAuth.Messaging { get { return this.Transport; } } + /// <summary> + /// Gets or sets a value indicating whether this message was deserialized as an incoming message. + /// </summary> + bool IProtocolMessage.Incoming { get; set; } + #endregion #region IDirectedProtocolMessage Members diff --git a/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs b/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs index 5be2837..f9844e4 100644 --- a/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs +++ b/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs @@ -102,6 +102,11 @@ namespace DotNetOpenAuth.OAuth.Messages { get { return this.ExtraData; } } + /// <summary> + /// Gets or sets a value indicating whether this message was deserialized as an incoming message. + /// </summary> + bool IProtocolMessage.Incoming { get; set; } + #endregion #region IDirectedProtocolMessage Members diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanRequest.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanRequest.cs index 3235d0d..611936d 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanRequest.cs @@ -95,5 +95,24 @@ namespace DotNetOpenAuth.OpenId.Messages { byte[] consumerPublicKeyExchange = this.Algorithm.CreateKeyExchange(); this.DiffieHellmanConsumerPublic = DiffieHellmanUtilities.EnsurePositive(consumerPublicKeyExchange); } + + /// <summary> + /// Creates a Provider's response to an incoming association request. + /// </summary> + /// <returns> + /// The appropriate association response message. + /// </returns> + /// <remarks> + /// <para>If an association can be successfully created, the + /// <see cref="AssociateSuccessfulResponse.CreateAssociation"/> method must not be + /// called by this method.</para> + /// <para>Successful association response messages will derive from <see cref="AssociateSuccessfulResponse"/>. + /// Failed association response messages will derive from <see cref="AssociateUnsuccessfulResponse"/>.</para> + /// </remarks> + protected override IProtocolMessage CreateResponseCore() { + var response = new AssociateDiffieHellmanResponse(); + response.AssociationType = this.AssociationType; + return response; + } } } diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs index 39b7516..0f3d729 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs @@ -33,44 +33,6 @@ namespace DotNetOpenAuth.OpenId.Messages { internal byte[] EncodedMacKey { get; set; } /// <summary> - /// Called to create the Association based on a request previously given by the Relying Party. - /// </summary> - /// <param name="request">The prior request for an association.</param> - /// <returns>The created association.</returns> - /// <remarks> - /// <para>The response message is updated to include the details of the created association by this method, - /// but the resulting association is <i>not</i> added to the association store and must be done by the caller.</para> - /// <para>This method is called by both the Provider and the Relying Party, but actually performs - /// quite different operations in either scenario.</para> - /// </remarks> - protected internal override Association CreateAssociation(AssociateRequest request) { - ErrorUtilities.VerifyArgumentNotNull(request, "request"); - ErrorUtilities.VerifyArgument(request is AssociateDiffieHellmanRequest, "request"); - - return this.CreateAssociation((AssociateDiffieHellmanRequest)request); - } - - /// <summary> - /// Called to create the Association based on a request previously given by the Relying Party. - /// </summary> - /// <param name="request">The request for an association.</param> - /// <returns>The created association.</returns> - /// <remarks> - /// <para>The response message is updated to include the details of the created association by this method, - /// but the resulting association is <i>not</i> added to the association store and must be done by the caller.</para> - /// <para>This method is called by both the Provider and the Relying Party, but actually performs - /// quite different operations in either scenario.</para> - /// </remarks> - private Association CreateAssociation(AssociateDiffieHellmanRequest request) { - // If the encoded mac key is already set, then this is an incoming message at the Relying Party. - if (this.EncodedMacKey == null) { - return this.CreateAssociationAtProvider(request); - } else { - return this.CreateAssociationAtRelyingParty(request); - } - } - - /// <summary> /// Creates the association at relying party side after the association response has been received. /// </summary> /// <param name="request">The original association request that was already sent and responded to.</param> @@ -78,11 +40,13 @@ namespace DotNetOpenAuth.OpenId.Messages { /// <remarks> /// The resulting association is <i>not</i> added to the association store and must be done by the caller. /// </remarks> - private Association CreateAssociationAtRelyingParty(AssociateDiffieHellmanRequest request) { + protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); + ErrorUtilities.VerifyArgument(request is AssociateDiffieHellmanRequest, "request"); + var diffieHellmanRequest = (AssociateDiffieHellmanRequest)request; HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(Protocol, this.SessionType); - byte[] associationSecret = DiffieHellmanUtilities.SHAHashXorSecret(hasher, request.Algorithm, this.DiffieHellmanServerPublic, this.EncodedMacKey); + byte[] associationSecret = DiffieHellmanUtilities.SHAHashXorSecret(hasher, diffieHellmanRequest.Algorithm, this.DiffieHellmanServerPublic, this.EncodedMacKey); Association association = HmacShaAssociation.Create(Protocol, this.AssociationType, this.AssociationHandle, associationSecret, TimeSpan.FromSeconds(this.ExpiresIn)); return association; @@ -97,8 +61,10 @@ namespace DotNetOpenAuth.OpenId.Messages { /// The response message is updated to include the details of the created association by this method, /// but the resulting association is <i>not</i> added to the association store and must be done by the caller. /// </remarks> - private Association CreateAssociationAtProvider(AssociateDiffieHellmanRequest request) { + protected override Association CreateAssociationAtProvider(AssociateRequest request) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); + ErrorUtilities.VerifyArgument(request is AssociateDiffieHellmanRequest, "request"); + var diffieHellmanRequest = (AssociateDiffieHellmanRequest)request; this.SessionType = this.SessionType ?? request.SessionType; @@ -113,12 +79,12 @@ namespace DotNetOpenAuth.OpenId.Messages { // using its part of a DH secret in order to decrypt the shared secret we just invented // above when we created the association. DiffieHellman dh = new DiffieHellmanManaged( - request.DiffieHellmanModulus ?? AssociateDiffieHellmanRequest.DefaultMod, - request.DiffieHellmanGen ?? AssociateDiffieHellmanRequest.DefaultGen, + diffieHellmanRequest.DiffieHellmanModulus ?? AssociateDiffieHellmanRequest.DefaultMod, + diffieHellmanRequest.DiffieHellmanGen ?? AssociateDiffieHellmanRequest.DefaultGen, AssociateDiffieHellmanRequest.DefaultX); HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(this.Protocol, this.SessionType); this.DiffieHellmanServerPublic = DiffieHellmanUtilities.EnsurePositive(dh.CreateKeyExchange()); - this.EncodedMacKey = DiffieHellmanUtilities.SHAHashXorSecret(hasher, dh, request.DiffieHellmanConsumerPublic, association.SecretKey); + this.EncodedMacKey = DiffieHellmanUtilities.SHAHashXorSecret(hasher, dh, diffieHellmanRequest.DiffieHellmanConsumerPublic, association.SecretKey); return association; } diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs index 1b885bf..3bc0a30 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs @@ -70,6 +70,7 @@ namespace DotNetOpenAuth.OpenId.Messages { AssociateRequest associateRequest; if (provider.Endpoint.IsTransportSecure()) { associateRequest = new AssociateUnencryptedRequest(provider.Endpoint); + associateRequest.AssociationType = provider.Protocol.Args.SignatureAlgorithm.HMAC_SHA1; } else { // TODO: apply security policies and our knowledge of the provider's OpenID version // to select the right association here. @@ -82,5 +83,48 @@ namespace DotNetOpenAuth.OpenId.Messages { return associateRequest; } + + /// <summary> + /// Creates a Provider's response to an incoming association request. + /// </summary> + /// <param name="associationStore">The association store where a new association (if created) will be stored. Must not be null.</param> + /// <returns> + /// The appropriate association response that is ready to be sent back to the Relying Party. + /// </returns> + /// <remarks> + /// <para>If an association is created, it will be automatically be added to the provided + /// association store.</para> + /// <para>Successful association response messages will derive from <see cref="AssociateSuccessfulResponse"/>. + /// Failed association response messages will derive from <see cref="AssociateUnsuccessfulResponse"/>.</para> + /// </remarks> + internal IProtocolMessage CreateResponse(IAssociationStore<AssociationRelyingPartyType> associationStore) { + ErrorUtilities.VerifyArgumentNotNull(associationStore, "associationStore"); + + var response = this.CreateResponseCore(); + + // Create and store the association if this is a successful response. + var successResponse = response as AssociateSuccessfulResponse; + if (successResponse != null) { + Association association = successResponse.CreateAssociation(this); + associationStore.StoreAssociation(AssociationRelyingPartyType.Smart, association); + } + + return response; + } + + /// <summary> + /// Creates a Provider's response to an incoming association request. + /// </summary> + /// <returns> + /// The appropriate association response message. + /// </returns> + /// <remarks> + /// <para>If an association can be successfully created, the + /// <see cref="AssociateSuccessfulResponse.CreateAssociation"/> method must not be + /// called by this method.</para> + /// <para>Successful association response messages will derive from <see cref="AssociateSuccessfulResponse"/>. + /// Failed association response messages will derive from <see cref="AssociateUnsuccessfulResponse"/>.</para> + /// </remarks> + protected abstract IProtocolMessage CreateResponseCore(); } } diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponse.cs index 8c6d39d..7d4ee04 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponse.cs @@ -21,6 +21,11 @@ namespace DotNetOpenAuth.OpenId.Messages { [DebuggerDisplay("OpenID {ProtocolVersion} associate response {AssociationHandle} {AssociationType} {SessionType}")] internal abstract class AssociateSuccessfulResponse : DirectResponseBase { /// <summary> + /// A flag indicating whether an association has already been created. + /// </summary> + private bool associationCreated; + + /// <summary> /// Gets or sets the association handle is used as a key to refer to this association in subsequent messages. /// </summary> /// <value>A string 255 characters or less in length. It MUST consist only of ASCII characters in the range 33-126 inclusive (printable non-whitespace characters). </value> @@ -62,6 +67,45 @@ namespace DotNetOpenAuth.OpenId.Messages { /// <para>This method is called by both the Provider and the Relying Party, but actually performs /// quite different operations in either scenario.</para> /// </remarks> - protected internal abstract Association CreateAssociation(AssociateRequest request); + internal Association CreateAssociation(AssociateRequest request) { + ErrorUtilities.VerifyArgumentNotNull(request, "request"); + ErrorUtilities.VerifyInternal(!this.associationCreated, "The association has already been created."); + Association association; + + // If this message is outgoing, then we need to initialize some common + // properties based on the created association. + if (this.Incoming) { + association = this.CreateAssociationAtRelyingParty(request); + } else { + association = this.CreateAssociationAtProvider(request); + this.ExpiresIn = association.SecondsTillExpiration; + this.AssociationHandle = association.Handle; + } + + this.associationCreated = true; + + return association; + } + + /// <summary> + /// Called to create the Association based on a request previously given by the Relying Party. + /// </summary> + /// <param name="request">The prior request for an association.</param> + /// <returns>The created association.</returns> + /// <remarks> + /// <para>The caller will update this message's <see cref="ExpiresIn"/> and <see cref="AssociationHandle"/> + /// properties based on the <see cref="Association"/> returned by this method, but any other + /// association type specific properties must be set by this method.</para> + /// <para>The response message is updated to include the details of the created association by this method, + /// but the resulting association is <i>not</i> added to the association store and must be done by the caller.</para> + /// </remarks> + protected abstract Association CreateAssociationAtProvider(AssociateRequest request); + + /// <summary> + /// Called to create the Association based on a request previously given by the Relying Party. + /// </summary> + /// <param name="request">The prior request for an association.</param> + /// <returns>The created association.</returns> + protected abstract Association CreateAssociationAtRelyingParty(AssociateRequest request); } } diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateUnencryptedRequest.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateUnencryptedRequest.cs index ada1d32..1b30ccd 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/AssociateUnencryptedRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateUnencryptedRequest.cs @@ -45,5 +45,24 @@ namespace DotNetOpenAuth.OpenId.Messages { Protocol.Args.SessionType.NoEncryption, SessionType); } + + /// <summary> + /// Creates a Provider's response to an incoming association request. + /// </summary> + /// <returns> + /// The appropriate association response message. + /// </returns> + /// <remarks> + /// <para>If an association can be successfully created, the + /// <see cref="AssociateSuccessfulResponse.CreateAssociation"/> method must not be + /// called by this method.</para> + /// <para>Successful association response messages will derive from <see cref="AssociateSuccessfulResponse"/>. + /// Failed association response messages will derive from <see cref="AssociateUnsuccessfulResponse"/>.</para> + /// </remarks> + protected override IProtocolMessage CreateResponseCore() { + var response = new AssociateUnencryptedResponse(); + response.AssociationType = this.AssociationType; + return response; + } } } diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateUnencryptedResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateUnencryptedResponse.cs index 3790963..2cc2d0e 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/AssociateUnencryptedResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateUnencryptedResponse.cs @@ -35,14 +35,28 @@ namespace DotNetOpenAuth.OpenId.Messages { /// <param name="request">The prior request for an association.</param> /// <returns>The created association.</returns> /// <remarks> + /// <para>The caller will update this message's + /// <see cref="AssociateSuccessfulResponse.ExpiresIn"/> and + /// <see cref="AssociateSuccessfulResponse.AssociationHandle"/> + /// properties based on the <see cref="Association"/> returned by this method, but any other + /// association type specific properties must be set by this method.</para> /// <para>The response message is updated to include the details of the created association by this method, /// but the resulting association is <i>not</i> added to the association store and must be done by the caller.</para> - /// <para>This method is called by both the Provider and the Relying Party, but actually performs - /// quite different operations in either scenario.</para> /// </remarks> - protected internal override Association CreateAssociation(AssociateRequest request) { - ////return HmacShaAssociation.Create(Protocol, this.AssociationType, AssociationRelyingPartyType. - throw new NotImplementedException(); + protected override Association CreateAssociationAtProvider(AssociateRequest request) { + Association association = HmacShaAssociation.Create(Protocol, this.AssociationType, AssociationRelyingPartyType.Smart); + this.MacKey = association.SecretKey; + return association; + } + + /// <summary> + /// Called to create the Association based on a request previously given by the Relying Party. + /// </summary> + /// <param name="request">The prior request for an association.</param> + /// <returns>The created association.</returns> + protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { + Association association = HmacShaAssociation.Create(Protocol, this.AssociationType, this.AssociationHandle, this.MacKey, TimeSpan.FromSeconds(this.ExpiresIn)); + return association; } } } diff --git a/src/DotNetOpenAuth/OpenId/Messages/DirectResponseBase.cs b/src/DotNetOpenAuth/OpenId/Messages/DirectResponseBase.cs index 7a7ded8..a1dc3ee 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/DirectResponseBase.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/DirectResponseBase.cs @@ -70,6 +70,11 @@ namespace DotNetOpenAuth.OpenId.Messages { get { return EmptyDictionary<string, string>.Instance; } } + /// <summary> + /// Gets or sets a value indicating whether this message was deserialized as an incoming message. + /// </summary> + public bool Incoming { get; set; } + #endregion /// <summary> diff --git a/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs b/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs index a8bc18b..101e4e3 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs @@ -114,7 +114,12 @@ namespace DotNetOpenAuth.OpenId.Messages { get { return EmptyDictionary<string, string>.Instance; } } - #endregion + /// <summary> + /// Gets or sets a value indicating whether this message was deserialized as an incoming message. + /// </summary> + public bool Incoming { get; set; } + + #endregion /// <summary> /// Gets the protocol used by this message. diff --git a/src/DotNetOpenAuth/OpenId/OpenIdProvider.cs b/src/DotNetOpenAuth/OpenId/OpenIdProvider.cs index 8902233..8ae1559 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdProvider.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdProvider.cs @@ -50,17 +50,9 @@ namespace DotNetOpenAuth.OpenId { var associateRequest = request as AssociateRequest; if (associateRequest != null) { var associateDiffieHellmanRequest = request as AssociateDiffieHellmanRequest; + var associateUnencryptedRequest = request as AssociateUnencryptedRequest; - AssociateSuccessfulResponse response; - if (associateDiffieHellmanRequest != null) { - response = new AssociateDiffieHellmanResponse(); - } else { - // TODO: code here - throw new NotImplementedException(); - } - response.AssociationType = associateDiffieHellmanRequest.AssociationType; - Association association = response.CreateAssociation(associateRequest); - this.AssociationStore.StoreAssociation(AssociationRelyingPartyType.Smart, association); + IProtocolMessage response = associateRequest.CreateResponse(this.AssociationStore); this.Channel.Send(response); } else { // TODO: code here diff --git a/src/DotNetOpenAuth/OpenId/OpenIdRelyingParty.cs b/src/DotNetOpenAuth/OpenId/OpenIdRelyingParty.cs index af239b1..cc7c5f5 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdRelyingParty.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdRelyingParty.cs @@ -20,6 +20,7 @@ namespace DotNetOpenAuth.OpenId { /// <summary> /// Initializes a new instance of the <see cref="OpenIdRelyingParty"/> class. /// </summary> + /// <param name="associationStore">The association store. If null, the relying party will always operate in "dumb mode".</param> public OpenIdRelyingParty(IAssociationStore<Uri> associationStore) { ErrorUtilities.VerifyArgumentNotNull(associationStore, "associationStore"); |