diff options
180 files changed, 2644 insertions, 1818 deletions
diff --git a/src/DotNetOpenAuth.Messaging/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.Messaging/Properties/AssemblyInfo.cs index 5088657..0aae730 100644 --- a/src/DotNetOpenAuth.Messaging/Properties/AssemblyInfo.cs +++ b/src/DotNetOpenAuth.Messaging/Properties/AssemblyInfo.cs @@ -50,13 +50,17 @@ using System.Web.UI; [assembly: InternalsVisibleTo("DotNetOpenAuth.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] [assembly: InternalsVisibleTo("DotNetOpenAuth.InfoCard, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] -[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenID, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.RelyingParty, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.Provider, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] [assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] [assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] #else [assembly: InternalsVisibleTo("DotNetOpenAuth.Test")] [assembly: InternalsVisibleTo("DotNetOpenAuth.InfoCard")] -[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenID")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.RelyingParty")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.Provider")] [assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth")] [assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth2")] #endif diff --git a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdProviderElement.cs b/src/DotNetOpenAuth.OpenId.Provider/Configuration/OpenIdProviderElement.cs index a594e86..6f5a043 100644 --- a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdProviderElement.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/Configuration/OpenIdProviderElement.cs @@ -16,6 +16,11 @@ namespace DotNetOpenAuth.Configuration { [ContractVerification(true)] internal class OpenIdProviderElement : ConfigurationElement { /// <summary> + /// The name of the <provider> sub-element. + /// </summary> + private const string ProviderElementName = "provider"; + + /// <summary> /// The name of the security sub-element. /// </summary> private const string SecuritySettingsConfigName = "security"; diff --git a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdProviderSecuritySettingsElement.cs b/src/DotNetOpenAuth.OpenId.Provider/Configuration/OpenIdProviderSecuritySettingsElement.cs index 0d8e8b4..0d8e8b4 100644 --- a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdProviderSecuritySettingsElement.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/Configuration/OpenIdProviderSecuritySettingsElement.cs diff --git a/src/DotNetOpenAuth.OpenId.Provider/DotNetOpenAuth.OpenId.Provider.csproj b/src/DotNetOpenAuth.OpenId.Provider/DotNetOpenAuth.OpenId.Provider.csproj new file mode 100644 index 0000000..627471f --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/DotNetOpenAuth.OpenId.Provider.csproj @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + </PropertyGroup> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.props" /> + <PropertyGroup> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{F8284738-3B5D-4733-A511-38C23F4A763F}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>DotNetOpenAuth</RootNamespace> + <AssemblyName>DotNetOpenAuth.OpenId.Provider</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + </PropertyGroup> + <ItemGroup> + <Compile Include="Configuration\OpenIdProviderElement.cs" /> + <Compile Include="Configuration\OpenIdProviderSecuritySettingsElement.cs" /> + <Compile Include="OpenId\Behaviors\AXFetchAsSregTransform.cs" /> + <Compile Include="OpenId\Behaviors\GsaIcamProviderProfile.cs" /> + <Compile Include="OpenId\Behaviors\PpidGeneration.cs" /> + <Compile Include="OpenId\ChannelElements\OpenIdProviderChannel.cs" /> + <Compile Include="OpenId\ChannelElements\ProviderSigningBindingElement.cs" /> + <Compile Include="OpenId\Extensions\ExtensionsInteropProviderHelper.cs" /> + <Compile Include="OpenId\HmacShaAsssociationProvider.cs" /> + <Compile Include="OpenId\Messages\AssociateDiffieHellmanProviderResponse.cs" /> + <Compile Include="OpenId\Messages\AssociateRequestProvider.cs" /> + <Compile Include="OpenId\Messages\AssociateSuccessfulResponseProvider.cs" /> + <Compile Include="OpenId\Messages\AssociateSuccessfulResponseProviderContract.cs" /> + <Compile Include="OpenId\Messages\AssociateUnencryptedResponseProvider.cs" /> + <Compile Include="OpenId\Messages\CheckAuthenticationResponseProvider.cs" /> + <Compile Include="OpenId\OpenIdProviderUtilities.cs" /> + <Compile Include="OpenId\Provider\AssociationDataBag.cs" /> + <Compile Include="OpenId\Provider\IdentityEndpoint.cs" /> + <Compile Include="OpenId\Provider\IdentityEndpointNormalizationEventArgs.cs" /> + <Compile Include="OpenId\Provider\IProviderAssociationStore.cs" /> + <Compile Include="OpenId\Provider\ProviderAssociationHandleEncoder.cs" /> + <Compile Include="OpenId\Provider\ProviderAssociationKeyStorage.cs" /> + <Compile Include="OpenId\Provider\AssociationRelyingPartyType.cs" /> + <Compile Include="OpenId\Provider\PrivatePersonalIdentifierProviderBase.cs" /> + <Compile Include="OpenId\Provider\AnonymousRequest.cs" /> + <Compile Include="OpenId\Provider\AnonymousRequestEventArgs.cs" /> + <Compile Include="OpenId\Provider\AuthenticationChallengeEventArgs.cs" /> + <Compile Include="OpenId\Provider\AuthenticationRequest.cs" /> + <Compile Include="OpenId\Provider\AutoResponsiveRequest.cs" /> + <Compile Include="OpenId\Provider\HostProcessedRequest.cs" /> + <Compile Include="OpenId\Provider\IAnonymousRequest.cs" /> + <Compile Include="OpenId\Provider\IAuthenticationRequest.cs" /> + <Compile Include="OpenId\Provider\IDirectedIdentityIdentifierProvider.cs" /> + <Compile Include="OpenId\Provider\IHostProcessedRequest.cs" /> + <Compile Include="OpenId\Provider\IErrorReporting.cs" /> + <Compile Include="OpenId\Provider\IProviderBehavior.cs" /> + <Compile Include="OpenId\Provider\IRequest.cs" /> + <Compile Include="OpenId\Provider\ProviderEndpoint.cs" /> + <Compile Include="OpenId\Provider\RelyingPartyDiscoveryResult.cs" /> + <Compile Include="OpenId\Provider\Request.cs" /> + <Compile Include="OpenId\Provider\RequestContract.cs" /> + <Compile Include="OpenId\Provider\StandardProviderApplicationStore.cs" /> + <Compile Include="OpenId\Provider\OpenIdProvider.cs" /> + <Compile Include="OpenId\Provider\ProviderSecuritySettings.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\DotNetOpenAuth.Messaging\DotNetOpenAuth.Messaging.csproj"> + <Project>{60426312-6AE5-4835-8667-37EDEA670222}</Project> + <Name>DotNetOpenAuth.Messaging</Name> + </ProjectReference> + <ProjectReference Include="..\DotNetOpenAuth.OpenId\DotNetOpenAuth.OpenId.csproj"> + <Project>{3896A32A-E876-4C23-B9B8-78E17D134CD3}</Project> + <Name>DotNetOpenAuth.OpenId</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <ItemGroup /> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" /> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " /> +</Project>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Behaviors/AXFetchAsSregTransform.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Behaviors/AXFetchAsSregTransform.cs new file mode 100644 index 0000000..e9fed88 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Behaviors/AXFetchAsSregTransform.cs @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------- +// <copyright file="AXFetchAsSregTransform.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Behaviors { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Extensions; + using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + using DotNetOpenAuth.OpenId.Provider; + using DotNetOpenAuth.OpenId.RelyingParty; + + /// <summary> + /// An Attribute Exchange and Simple Registration filter to make all incoming attribute + /// requests look like Simple Registration requests, and to convert the response + /// to the originally requested extension and format. + /// </summary> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Abbreviation")] + public sealed class AXFetchAsSregProviderTransform : AXFetchAsSregTransform, IProviderBehavior { + /// <summary> + /// Initializes a new instance of the <see cref="AXFetchAsSregProviderTransform"/> class. + /// </summary> + public AXFetchAsSregProviderTransform() { + } + + #region IProviderBehavior Members + + /// <summary> + /// Applies a well known set of security requirements to a default set of security settings. + /// </summary> + /// <param name="securitySettings">The security settings to enhance with the requirements of this profile.</param> + /// <remarks> + /// Care should be taken to never decrease security when applying a profile. + /// Profiles should only enhance security requirements to avoid being + /// incompatible with each other. + /// </remarks> + void IProviderBehavior.ApplySecuritySettings(ProviderSecuritySettings securitySettings) { + // Nothing to do here. + } + + /// <summary> + /// Called when a request is received by the Provider. + /// </summary> + /// <param name="request">The incoming request.</param> + /// <returns> + /// <c>true</c> if this behavior owns this request and wants to stop other behaviors + /// from handling it; <c>false</c> to allow other behaviors to process this request. + /// </returns> + /// <remarks> + /// Implementations may set a new value to <see cref="IRequest.SecuritySettings"/> but + /// should not change the properties on the instance of <see cref="ProviderSecuritySettings"/> + /// itself as that instance may be shared across many requests. + /// </remarks> + bool IProviderBehavior.OnIncomingRequest(IRequest request) { + var extensionRequest = request as Provider.HostProcessedRequest; + if (extensionRequest != null) { + extensionRequest.UnifyExtensionsAsSreg(); + } + + return false; + } + + /// <summary> + /// Called when the Provider is preparing to send a response to an authentication request. + /// </summary> + /// <param name="request">The request that is configured to generate the outgoing response.</param> + /// <returns> + /// <c>true</c> if this behavior owns this request and wants to stop other behaviors + /// from handling it; <c>false</c> to allow other behaviors to process this request. + /// </returns> + bool IProviderBehavior.OnOutgoingResponse(Provider.IAuthenticationRequest request) { + request.ConvertSregToMatchRequest(); + return false; + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Behaviors/GsaIcamProviderProfile.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Behaviors/GsaIcamProviderProfile.cs new file mode 100644 index 0000000..020de09 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Behaviors/GsaIcamProviderProfile.cs @@ -0,0 +1,192 @@ +//----------------------------------------------------------------------- +// <copyright file="GsaIcamProfile.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Behaviors { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Linq; + using DotNetOpenAuth.Configuration; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; + using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + using DotNetOpenAuth.OpenId.Provider; + using DotNetOpenAuth.OpenId.RelyingParty; + + /// <summary> + /// Implements the Identity, Credential, & Access Management (ICAM) OpenID 2.0 Profile + /// for the General Services Administration (GSA). + /// </summary> + /// <remarks> + /// <para>Relying parties that include this profile are always held to the terms required by the profile, + /// but Providers are only affected by the special behaviors of the profile when the RP specifically + /// indicates that they want to use this profile. </para> + /// </remarks> + [Serializable] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Icam", Justification = "Acronym")] + public sealed class GsaIcamProviderProfile : GsaIcamProfile, IProviderBehavior { + /// <summary> + /// The maximum time a shared association can live. + /// </summary> + private static readonly TimeSpan MaximumAssociationLifetime = TimeSpan.FromSeconds(86400); + + /// <summary> + /// Initializes a new instance of the <see cref="GsaIcamProfile"/> class. + /// </summary> + public GsaIcamProviderProfile() { + if (DisableSslRequirement) { + Logger.OpenId.Warn("GSA level 1 behavior has its RequireSsl requirement disabled."); + } + } + + /// <summary> + /// Gets or sets the provider for generating PPID identifiers. + /// </summary> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ppid", Justification = "Acronym")] + public static IDirectedIdentityIdentifierProvider PpidIdentifierProvider { get; set; } + + #region IProviderBehavior Members + + /// <summary> + /// Adapts the default security settings to the requirements of this behavior. + /// </summary> + /// <param name="securitySettings">The original security settings.</param> + void IProviderBehavior.ApplySecuritySettings(ProviderSecuritySettings securitySettings) { + if (securitySettings.MaximumHashBitLength < 256) { + securitySettings.MaximumHashBitLength = 256; + } + + SetMaximumAssociationLifetimeToNotExceed(Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA256, MaximumAssociationLifetime, securitySettings); + SetMaximumAssociationLifetimeToNotExceed(Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, MaximumAssociationLifetime, securitySettings); + } + + /// <summary> + /// Called when a request is received by the Provider. + /// </summary> + /// <param name="request">The incoming request.</param> + /// <returns> + /// <c>true</c> if this behavior owns this request and wants to stop other behaviors + /// from handling it; <c>false</c> to allow other behaviors to process this request. + /// </returns> + /// <remarks> + /// Implementations may set a new value to <see cref="IRequest.SecuritySettings"/> but + /// should not change the properties on the instance of <see cref="ProviderSecuritySettings"/> + /// itself as that instance may be shared across many requests. + /// </remarks> + bool IProviderBehavior.OnIncomingRequest(IRequest request) { + var hostProcessedRequest = request as IHostProcessedRequest; + if (hostProcessedRequest != null) { + // Only apply our special policies if the RP requested it. + var papeRequest = request.GetExtension<PolicyRequest>(); + if (papeRequest != null) { + if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1)) { + // Whenever we see this GSA policy requested, we MUST also see the PPID policy requested. + ErrorUtilities.VerifyProtocol(papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier), BehaviorStrings.PapeRequestMissingRequiredPolicies); + ErrorUtilities.VerifyProtocol(string.Equals(hostProcessedRequest.Realm.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal) || DisableSslRequirement, BehaviorStrings.RealmMustBeHttps); + + // Apply GSA-specific security to this individual request. + request.SecuritySettings.RequireSsl = !DisableSslRequirement; + return true; + } + } + } + + return false; + } + + /// <summary> + /// Called when the Provider is preparing to send a response to an authentication request. + /// </summary> + /// <param name="request">The request that is configured to generate the outgoing response.</param> + /// <returns> + /// <c>true</c> if this behavior owns this request and wants to stop other behaviors + /// from handling it; <c>false</c> to allow other behaviors to process this request. + /// </returns> + bool IProviderBehavior.OnOutgoingResponse(Provider.IAuthenticationRequest request) { + bool result = false; + + // Nothing to do for negative assertions. + if (!request.IsAuthenticated.Value) { + return result; + } + + var requestInternal = (Provider.AuthenticationRequest)request; + var responseMessage = (IProtocolMessageWithExtensions)requestInternal.Response; + + // Only apply our special policies if the RP requested it. + var papeRequest = request.GetExtension<PolicyRequest>(); + if (papeRequest != null) { + var papeResponse = responseMessage.Extensions.OfType<PolicyResponse>().SingleOrDefault(); + if (papeResponse == null) { + request.AddResponseExtension(papeResponse = new PolicyResponse()); + } + + if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1)) { + result = true; + if (!papeResponse.ActualPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1)) { + papeResponse.ActualPolicies.Add(AuthenticationPolicies.USGovernmentTrustLevel1); + } + + // The spec requires that the OP perform discovery and if that fails, it must either sternly + // warn the user of a potential threat or just abort the authentication. + // We can't verify that the OP displayed anything to the user at this level, but we can + // at least verify that the OP performed the discovery on the realm and halt things if it didn't. + ErrorUtilities.VerifyHost(requestInternal.HasRealmDiscoveryBeenPerformed, BehaviorStrings.RealmDiscoveryNotPerformed); + } + + if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { + ErrorUtilities.VerifyProtocol(request.ClaimedIdentifier == request.LocalIdentifier, OpenIdStrings.DelegatingIdentifiersNotAllowed); + + // Mask the user's identity with a PPID. + ErrorUtilities.VerifyHost(PpidIdentifierProvider != null, BehaviorStrings.PpidProviderNotGiven); + Identifier ppidIdentifier = PpidIdentifierProvider.GetIdentifier(request.LocalIdentifier, request.Realm); + requestInternal.ResetClaimedAndLocalIdentifiers(ppidIdentifier); + + // Indicate that the RP is receiving a PPID claimed_id + if (!papeResponse.ActualPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { + papeResponse.ActualPolicies.Add(AuthenticationPolicies.PrivatePersonalIdentifier); + } + } + + if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { + ErrorUtilities.VerifyProtocol( + !responseMessage.Extensions.OfType<ClaimsResponse>().Any() && + !responseMessage.Extensions.OfType<FetchResponse>().Any(), + BehaviorStrings.PiiIncludedWithNoPiiPolicy); + + // If no PII is given in extensions, and the claimed_id is a PPID, then we can state we issue no PII. + if (papeResponse.ActualPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { + if (!papeResponse.ActualPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { + papeResponse.ActualPolicies.Add(AuthenticationPolicies.NoPersonallyIdentifiableInformation); + } + } + } + + Reporting.RecordEventOccurrence(this, "OP"); + } + + return result; + } + + #endregion + + /// <summary> + /// Ensures the maximum association lifetime does not exceed a given limit. + /// </summary> + /// <param name="associationType">Type of the association.</param> + /// <param name="maximumLifetime">The maximum lifetime.</param> + /// <param name="securitySettings">The security settings to adjust.</param> + private static void SetMaximumAssociationLifetimeToNotExceed(string associationType, TimeSpan maximumLifetime, ProviderSecuritySettings securitySettings) { + Contract.Requires(!String.IsNullOrEmpty(associationType)); + Contract.Requires(maximumLifetime.TotalSeconds > 0); + if (!securitySettings.AssociationLifetimes.ContainsKey(associationType) || + securitySettings.AssociationLifetimes[associationType] > maximumLifetime) { + securitySettings.AssociationLifetimes[associationType] = maximumLifetime; + } + } + } +} diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/PpidGeneration.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Behaviors/PpidGeneration.cs index a465611..a465611 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/PpidGeneration.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Behaviors/PpidGeneration.cs diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/ChannelElements/OpenIdProviderChannel.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/ChannelElements/OpenIdProviderChannel.cs new file mode 100644 index 0000000..57448d8 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/ChannelElements/OpenIdProviderChannel.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------- +// <copyright file="OpenIdProviderChannel.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.ChannelElements { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.OpenId.Provider; + using DotNetOpenAuth.Messaging.Bindings; + using System.Diagnostics.Contracts; + + internal class OpenIdProviderChannel : OpenIdChannel { + /// <summary> + /// Initializes a new instance of the <see cref="OpenIdChannel"/> class + /// for use by a Provider. + /// </summary> + /// <param name="cryptoKeyStore">The OpenID Provider's association store or handle encoder.</param> + /// <param name="nonceStore">The nonce store to use.</param> + /// <param name="securitySettings">The security settings.</param> + internal OpenIdProviderChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings) + : this(cryptoKeyStore, nonceStore, new OpenIdMessageFactory(), securitySettings) { + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); + } + + /// <summary> + /// Initializes a new instance of the <see cref="OpenIdChannel"/> class + /// for use by a Provider. + /// </summary> + /// <param name="cryptoKeyStore">The association store to use.</param> + /// <param name="nonceStore">The nonce store to use.</param> + /// <param name="messageTypeProvider">An object that knows how to distinguish the various OpenID message types for deserialization purposes.</param> + /// <param name="securitySettings">The security settings.</param> + private OpenIdChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, ProviderSecuritySettings securitySettings) : + this(messageTypeProvider, InitializeBindingElements(cryptoKeyStore, nonceStore, securitySettings)) { + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); + Contract.Requires<ArgumentNullException>(messageTypeProvider != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); + } + + /// <summary> + /// Initializes the binding elements. + /// </summary> + /// <param name="cryptoKeyStore">The OpenID Provider's crypto key store.</param> + /// <param name="nonceStore">The nonce store to use.</param> + /// <param name="securitySettings">The security settings to apply. Must be an instance of either <see cref="RelyingPartySecuritySettings"/> or <see cref="ProviderSecuritySettings"/>.</param> + /// <returns> + /// An array of binding elements which may be used to construct the channel. + /// </returns> + private static IChannelBindingElement[] InitializeBindingElements(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings) { + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); + Contract.Requires<ArgumentNullException>(nonceStore != null); + + SigningBindingElement signingElement; + signingElement = new SigningBindingElement(cryptoKeyStore, securitySettings); + + var extensionFactory = OpenIdExtensionFactoryAggregator.LoadFromConfiguration(); + + List<IChannelBindingElement> elements = new List<IChannelBindingElement>(8); + elements.Add(new ExtensionsBindingElement(extensionFactory, securitySettings)); + elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true)); + elements.Add(new StandardExpirationBindingElement()); + elements.Add(signingElement); + + return elements.ToArray(); + } + + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/ChannelElements/ProviderSigningBindingElement.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/ChannelElements/ProviderSigningBindingElement.cs new file mode 100644 index 0000000..18a992c --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/ChannelElements/ProviderSigningBindingElement.cs @@ -0,0 +1,217 @@ +//----------------------------------------------------------------------- +// <copyright file="ProviderSigningBindingElement.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.ChannelElements { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.OpenId.Provider; + using System.Diagnostics.Contracts; + using DotNetOpenAuth.OpenId.Messages; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Bindings; + + internal class ProviderSigningBindingElement : SigningBindingElement { + /// <summary> + /// The association store used by Providers to look up the secrets needed for signing. + /// </summary> + private readonly IProviderAssociationStore opAssociations; + + /// <summary> + /// The security settings at the Provider. + /// Only defined when this element is instantiated to service a Provider. + /// </summary> + private readonly ProviderSecuritySettings opSecuritySettings; + + /// <summary> + /// Initializes a new instance of the SigningBindingElement class for use by a Provider. + /// </summary> + /// <param name="associationStore">The association store used to look up the secrets needed for signing.</param> + /// <param name="securitySettings">The security settings.</param> + internal ProviderSigningBindingElement(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { + Contract.Requires<ArgumentNullException>(associationStore != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); + + this.opAssociations = associationStore; + this.opSecuritySettings = securitySettings; + } + + /// <summary> + /// Gets a value indicating whether this binding element is on a Provider channel. + /// </summary> + protected override bool IsOnProvider { + get { return true; } + } + + public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) { + var result = base.ProcessOutgoingMessage(message); + if (result != null) { + return result; + } + + var signedMessage = message as ITamperResistantOpenIdMessage; + if (signedMessage != null) { + Logger.Bindings.DebugFormat("Signing {0} message.", message.GetType().Name); + Association association = this.GetAssociation(signedMessage); + signedMessage.AssociationHandle = association.Handle; + signedMessage.SignedParameterOrder = this.GetSignedParameterOrder(signedMessage); + signedMessage.Signature = this.GetSignature(signedMessage, association); + return MessageProtections.TamperProtection; + } + + return null; + } + + protected override Association GetAssociation(ITamperResistantOpenIdMessage signedMessage) { + Contract.Requires<ArgumentNullException>(signedMessage != null); + + // We're on a Provider to either sign (smart/dumb) or verify a dumb signature. + bool signing = string.IsNullOrEmpty(signedMessage.Signature); + + if (signing) { + // If the RP has no replay protection, coerce use of a private association + // instead of a shared one (if security settings indicate) + // to protect the authenticating user from replay attacks. + bool forcePrivateAssociation = this.opSecuritySettings.ProtectDownlevelReplayAttacks + && IsRelyingPartyVulnerableToReplays(null, (IndirectSignedResponse)signedMessage); + + if (forcePrivateAssociation) { + if (!string.IsNullOrEmpty(signedMessage.AssociationHandle)) { + Logger.Signatures.Info("An OpenID 1.x authentication request with a shared association handle will be responded to with a private association in order to provide OP-side replay protection."); + } + + return this.GetDumbAssociationForSigning(); + } else { + return this.GetSpecificAssociation(signedMessage) ?? this.GetDumbAssociationForSigning(); + } + } else { + return this.GetSpecificAssociation(signedMessage); + } + } + + protected override Association GetSpecificAssociation(ITamperResistantOpenIdMessage signedMessage) { + Association association = null; + + if (!string.IsNullOrEmpty(signedMessage.AssociationHandle)) { + IndirectSignedResponse indirectSignedMessage = signedMessage as IndirectSignedResponse; + + // Since we have an association handle, we're either signing with a smart association, + // or verifying a dumb one. + bool signing = string.IsNullOrEmpty(signedMessage.Signature); + bool isPrivateAssociation = !signing; + association = this.opAssociations.Deserialize(signedMessage, isPrivateAssociation, signedMessage.AssociationHandle); + if (association == null) { + // There was no valid association with the requested handle. + // Let's tell the RP to forget about that association. + signedMessage.InvalidateHandle = signedMessage.AssociationHandle; + signedMessage.AssociationHandle = null; + } + } + + return association; + } + + /// <summary> + /// Gets a private Provider association used for signing messages in "dumb" mode. + /// </summary> + /// <returns>An existing or newly created association.</returns> + protected override Association GetDumbAssociationForSigning() { + // If no assoc_handle was given or it was invalid, the only thing + // left to do is sign a message using a 'dumb' mode association. + Protocol protocol = Protocol.Default; + Association association = HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.HMAC_SHA256, AssociationRelyingPartyType.Dumb, this.opAssociations, this.opSecuritySettings); + return association; + } + + protected override MessageProtections VerifySignatureByUnrecognizedHandle(IProtocolMessage message, ITamperResistantOpenIdMessage signedMessage, MessageProtections protectionsApplied) { + // If we're on the Provider, then the RP sent us a check_auth with a signature + // we don't have an association for. (It may have expired, or it may be a faulty RP). + throw new InvalidSignatureException(message); + } + + /// <summary> + /// Determines whether the relying party sending an authentication request is + /// vulnerable to replay attacks. + /// </summary> + /// <param name="request">The request message from the Relying Party. Useful, but may be null for conservative estimate results.</param> + /// <param name="response">The response message to be signed.</param> + /// <returns> + /// <c>true</c> if the relying party is vulnerable; otherwise, <c>false</c>. + /// </returns> + private static bool IsRelyingPartyVulnerableToReplays(SignedResponseRequest request, IndirectSignedResponse response) { + Contract.Requires<ArgumentNullException>(response != null); + + // OpenID 2.0 includes replay protection as part of the protocol. + if (response.Version.Major >= 2) { + return false; + } + + // This library's RP may be on the remote end, and may be using 1.x merely because + // discovery on the Claimed Identifier suggested this was a 1.x OP. + // Since this library's RP has a built-in request_nonce parameter for replay + // protection, we'll allow for that. + var returnToArgs = HttpUtility.ParseQueryString(response.ReturnTo.Query); + if (!string.IsNullOrEmpty(returnToArgs[ReturnToNonceBindingElement.NonceParameter])) { + return false; + } + + // If the OP endpoint _AND_ RP return_to URL uses HTTPS then no one + // can steal and replay the positive assertion. + // We can only ascertain this if the request message was handed to us + // so we know what our own OP endpoint is. If we don't have a request + // message, then we'll default to assuming it's insecure. + if (request != null) { + if (request.Recipient.IsTransportSecure() && response.Recipient.IsTransportSecure()) { + return false; + } + } + + // Nothing left to protect against replays. RP is vulnerable. + return true; + } + + /// <summary> + /// Gets the value to use for the openid.signed parameter. + /// </summary> + /// <param name="signedMessage">The signable message.</param> + /// <returns> + /// A comma-delimited list of parameter names, omitting the 'openid.' prefix, that determines + /// the inclusion and order of message parts that will be signed. + /// </returns> + private string GetSignedParameterOrder(ITamperResistantOpenIdMessage signedMessage) { + Contract.Requires<InvalidOperationException>(this.Channel != null); + Contract.Requires<ArgumentNullException>(signedMessage != null); + + Protocol protocol = Protocol.Lookup(signedMessage.Version); + + MessageDescription description = this.Channel.MessageDescriptions.Get(signedMessage); + var signedParts = from part in description.Mapping.Values + where (part.RequiredProtection & System.Net.Security.ProtectionLevel.Sign) != 0 + && part.GetValue(signedMessage) != null + select part.Name; + string prefix = Protocol.V20.openid.Prefix; + ErrorUtilities.VerifyInternal(signedParts.All(name => name.StartsWith(prefix, StringComparison.Ordinal)), "All signed message parts must start with 'openid.'."); + + if (this.opSecuritySettings.SignOutgoingExtensions) { + // Tack on any ExtraData parameters that start with 'openid.'. + List<string> extraSignedParameters = new List<string>(signedMessage.ExtraData.Count); + foreach (string key in signedMessage.ExtraData.Keys) { + if (key.StartsWith(protocol.openid.Prefix, StringComparison.Ordinal)) { + extraSignedParameters.Add(key); + } else { + Logger.Signatures.DebugFormat("The extra parameter '{0}' will not be signed because it does not start with 'openid.'.", key); + } + } + signedParts = signedParts.Concat(extraSignedParameters); + } + + int skipLength = prefix.Length; + string signedFields = string.Join(",", signedParts.Select(name => name.Substring(skipLength)).ToArray()); + return signedFields; + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Extensions/ExtensionsInteropProviderHelper.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Extensions/ExtensionsInteropProviderHelper.cs new file mode 100644 index 0000000..2f8ac2f --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Extensions/ExtensionsInteropProviderHelper.cs @@ -0,0 +1,161 @@ +//----------------------------------------------------------------------- +// <copyright file="ExtensionsInteropProviderHelper.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Extensions { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Linq; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + using DotNetOpenAuth.OpenId.Messages; + + /// <summary> + /// A set of methods designed to assist in improving interop across different + /// OpenID implementations and their extensions. + /// </summary> + public static class ExtensionsInteropProviderHelper { + /// <summary> + /// Transforms an AX attribute type URI from the axschema.org format into a given format. + /// </summary> + /// <param name="axSchemaOrgFormatTypeUri">The ax schema org format type URI.</param> + /// <param name="targetFormat">The target format. Only one flag should be set.</param> + /// <returns>The AX attribute type URI in the target format.</returns> + internal static string TransformAXFormatTestHook(string axSchemaOrgFormatTypeUri, AXAttributeFormats targetFormat) { + return ExtensionsInteropHelper.TransformAXFormat(axSchemaOrgFormatTypeUri, targetFormat); + } + + /// <summary> + /// Looks for Simple Registration and Attribute Exchange (all known formats) + /// request extensions and returns them as a Simple Registration extension, + /// and adds the new extension to the original request message if it was absent. + /// </summary> + /// <param name="request">The authentication request.</param> + /// <returns> + /// The Simple Registration request if found, + /// or a fabricated one based on the Attribute Exchange extension if found, + /// or <c>null</c> if no attribute extension request is found.</returns> + internal static ClaimsRequest UnifyExtensionsAsSreg(this Provider.IHostProcessedRequest request) { + Contract.Requires<ArgumentNullException>(request != null); + + var req = (Provider.HostProcessedRequest)request; + var sreg = req.GetExtension<ClaimsRequest>(); + if (sreg != null) { + return sreg; + } + + var ax = req.GetExtension<FetchRequest>(); + if (ax != null) { + sreg = new ClaimsRequest(SimpleRegistration.Constants.sreg_ns); + sreg.Synthesized = true; + ((IProtocolMessageWithExtensions)req.RequestMessage).Extensions.Add(sreg); + sreg.BirthDate = GetDemandLevelFor(ax, WellKnownAttributes.BirthDate.WholeBirthDate); + sreg.Country = GetDemandLevelFor(ax, WellKnownAttributes.Contact.HomeAddress.Country); + sreg.Email = GetDemandLevelFor(ax, WellKnownAttributes.Contact.Email); + sreg.FullName = GetDemandLevelFor(ax, WellKnownAttributes.Name.FullName); + sreg.Gender = GetDemandLevelFor(ax, WellKnownAttributes.Person.Gender); + sreg.Language = GetDemandLevelFor(ax, WellKnownAttributes.Preferences.Language); + sreg.Nickname = GetDemandLevelFor(ax, WellKnownAttributes.Name.Alias); + sreg.PostalCode = GetDemandLevelFor(ax, WellKnownAttributes.Contact.HomeAddress.PostalCode); + sreg.TimeZone = GetDemandLevelFor(ax, WellKnownAttributes.Preferences.TimeZone); + } + + return sreg; + } + + /// <summary> + /// Converts the Simple Registration extension response to whatever format the original + /// attribute request extension came in. + /// </summary> + /// <param name="request">The authentication request with the response extensions already added.</param> + /// <remarks> + /// If the original attribute request came in as AX, the Simple Registration extension is converted + /// to an AX response and then the Simple Registration extension is removed from the response. + /// </remarks> + internal static void ConvertSregToMatchRequest(this Provider.IHostProcessedRequest request) { + var req = (Provider.HostProcessedRequest)request; + var response = req.Response as IProtocolMessageWithExtensions; // negative responses don't support extensions. + var sregRequest = request.GetExtension<ClaimsRequest>(); + if (sregRequest != null && response != null) { + if (sregRequest.Synthesized) { + var axRequest = request.GetExtension<FetchRequest>(); + ErrorUtilities.VerifyInternal(axRequest != null, "How do we have a synthesized Sreg request without an AX request?"); + + var sregResponse = response.Extensions.OfType<ClaimsResponse>().SingleOrDefault(); + if (sregResponse == null) { + // No Sreg response to copy from. + return; + } + + // Remove the sreg response since the RP didn't ask for it. + response.Extensions.Remove(sregResponse); + + AXAttributeFormats format = ExtensionsInteropHelper.DetectAXFormat(axRequest.Attributes.Select(att => att.TypeUri)); + if (format == AXAttributeFormats.None) { + // No recognized AX attributes were requested. + return; + } + + var axResponse = response.Extensions.OfType<FetchResponse>().SingleOrDefault(); + if (axResponse == null) { + axResponse = new FetchResponse(); + response.Extensions.Add(axResponse); + } + + AddAXAttributeValue(axResponse, WellKnownAttributes.BirthDate.WholeBirthDate, format, sregResponse.BirthDateRaw); + AddAXAttributeValue(axResponse, WellKnownAttributes.Contact.HomeAddress.Country, format, sregResponse.Country); + AddAXAttributeValue(axResponse, WellKnownAttributes.Contact.HomeAddress.PostalCode, format, sregResponse.PostalCode); + AddAXAttributeValue(axResponse, WellKnownAttributes.Contact.Email, format, sregResponse.Email); + AddAXAttributeValue(axResponse, WellKnownAttributes.Name.FullName, format, sregResponse.FullName); + AddAXAttributeValue(axResponse, WellKnownAttributes.Name.Alias, format, sregResponse.Nickname); + AddAXAttributeValue(axResponse, WellKnownAttributes.Preferences.TimeZone, format, sregResponse.TimeZone); + AddAXAttributeValue(axResponse, WellKnownAttributes.Preferences.Language, format, sregResponse.Language); + if (sregResponse.Gender.HasValue) { + AddAXAttributeValue(axResponse, WellKnownAttributes.Person.Gender, format, ExtensionsInteropHelper.genderEncoder.Encode(sregResponse.Gender)); + } + } + } + } + + /// <summary> + /// Adds the AX attribute value to the response if it is non-empty. + /// </summary> + /// <param name="ax">The AX Fetch response to add the attribute value to.</param> + /// <param name="typeUri">The attribute type URI in axschema.org format.</param> + /// <param name="format">The target format of the actual attribute to write out.</param> + /// <param name="value">The value of the attribute.</param> + private static void AddAXAttributeValue(FetchResponse ax, string typeUri, AXAttributeFormats format, string value) { + if (!string.IsNullOrEmpty(value)) { + string targetTypeUri = ExtensionsInteropHelper.TransformAXFormat(typeUri, format); + if (!ax.Attributes.Contains(targetTypeUri)) { + ax.Attributes.Add(targetTypeUri, value); + } + } + } + + /// <summary> + /// Gets the demand level for an AX attribute. + /// </summary> + /// <param name="ax">The AX fetch request to search for the attribute.</param> + /// <param name="typeUri">The type URI of the attribute in axschema.org format.</param> + /// <returns>The demand level for the attribute.</returns> + private static DemandLevel GetDemandLevelFor(FetchRequest ax, string typeUri) { + Contract.Requires<ArgumentNullException>(ax != null); + Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri)); + + foreach (AXAttributeFormats format in ExtensionsInteropHelper.ForEachFormat(AXAttributeFormats.All)) { + string typeUriInFormat = ExtensionsInteropHelper.TransformAXFormat(typeUri, format); + if (ax.Attributes.Contains(typeUriInFormat)) { + return ax.Attributes[typeUriInFormat].IsRequired ? DemandLevel.Require : DemandLevel.Request; + } + } + + return DemandLevel.NoRequest; + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/HmacShaAsssociationProvider.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/HmacShaAsssociationProvider.cs new file mode 100644 index 0000000..37e410c --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/HmacShaAsssociationProvider.cs @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------- +// <copyright file="HmacShaAsssociationProvider.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Diagnostics.Contracts; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Provider; + + internal static class HmacShaAsssociationProvider : HmacShaAssociation { + /// <summary> + /// The default lifetime of a shared association when no lifetime is given + /// for a specific association type. + /// </summary> + private static readonly TimeSpan DefaultMaximumLifetime = TimeSpan.FromDays(14); + + /// <summary> + /// Creates a new association of a given type at an OpenID Provider. + /// </summary> + /// <param name="protocol">The protocol.</param> + /// <param name="associationType">Type of the association (i.e. HMAC-SHA1 or HMAC-SHA256)</param> + /// <param name="associationUse">A value indicating whether the new association will be used privately by the Provider for "dumb mode" authentication + /// or shared with the Relying Party for "smart mode" authentication.</param> + /// <param name="associationStore">The Provider's association store.</param> + /// <param name="securitySettings">The security settings of the Provider.</param> + /// <returns> + /// The newly created association. + /// </returns> + /// <remarks> + /// The new association is NOT automatically put into an association store. This must be done by the caller. + /// </remarks> + internal static HmacShaAssociation Create(Protocol protocol, string associationType, AssociationRelyingPartyType associationUse, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { + Contract.Requires<ArgumentNullException>(protocol != null); + Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType)); + Contract.Requires<ArgumentNullException>(associationStore != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); + Contract.Ensures(Contract.Result<HmacShaAssociation>() != null); + + int secretLength = GetSecretLength(protocol, associationType); + + // Generate the secret that will be used for signing + byte[] secret = MessagingUtilities.GetCryptoRandomData(secretLength); + + TimeSpan lifetime; + if (associationUse == AssociationRelyingPartyType.Smart) { + if (!securitySettings.AssociationLifetimes.TryGetValue(associationType, out lifetime)) { + lifetime = DefaultMaximumLifetime; + } + } else { + lifetime = DumbSecretLifetime; + } + + string handle = associationStore.Serialize(secret, DateTime.UtcNow + lifetime, associationUse == AssociationRelyingPartyType.Dumb); + + Contract.Assert(protocol != null); // All the way up to the method call, the condition holds, yet we get a Requires failure next + Contract.Assert(secret != null); + Contract.Assert(!String.IsNullOrEmpty(associationType)); + var result = Create(protocol, associationType, handle, secret, lifetime); + return result; + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateDiffieHellmanProviderResponse.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateDiffieHellmanProviderResponse.cs new file mode 100644 index 0000000..80743f7 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateDiffieHellmanProviderResponse.cs @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------- +// <copyright file="AssociateDiffieHellmanResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Messages { + using System; + using System.Diagnostics.Contracts; + using System.Security.Cryptography; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Reflection; + using DotNetOpenAuth.OpenId.Provider; + using Org.Mentalis.Security.Cryptography; + + /// <summary> + /// The successful Diffie-Hellman association response message. + /// </summary> + /// <remarks> + /// Association response messages are described in OpenID 2.0 section 8.2. This type covers section 8.2.3. + /// </remarks> + internal class AssociateDiffieHellmanProviderResponse : AssociateDiffieHellmanResponse { + /// <summary> + /// Initializes a new instance of the <see cref="AssociateDiffieHellmanProviderResponse"/> class. + /// </summary> + /// <param name="responseVersion">The OpenID version of the response message.</param> + /// <param name="originatingRequest">The originating request.</param> + internal AssociateDiffieHellmanProviderResponse(Version responseVersion, AssociateDiffieHellmanRequest originatingRequest) + : base(responseVersion, originatingRequest) { + } + + /// <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> + /// <returns>The newly created association.</returns> + /// <remarks> + /// The resulting association is <i>not</i> added to the association store and must be done by the caller. + /// </remarks> + protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { + throw new NotImplementedException(); + } + + /// <summary> + /// Creates the association at the provider side after the association request has been received. + /// </summary> + /// <param name="request">The association request.</param> + /// <param name="associationStore">The OpenID Provider's association store or handle encoder.</param> + /// <param name="securitySettings">The security settings of the Provider.</param> + /// <returns> + /// The newly created association. + /// </returns> + /// <remarks> + /// 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> + protected override Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { + var diffieHellmanRequest = request as AssociateDiffieHellmanRequest; + ErrorUtilities.VerifyInternal(diffieHellmanRequest != null, "Expected a DH request type."); + + this.SessionType = this.SessionType ?? request.SessionType; + + // Go ahead and create the association first, complete with its secret that we're about to share. + Association association = HmacShaAssociation.Create(this.Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings); + + // We now need to securely communicate the secret to the relying party using Diffie-Hellman. + // We do this by performing a DH algorithm on the secret and setting a couple of properties + // that will be transmitted to the Relying Party. The RP will perform an inverse operation + // using its part of a DH secret in order to decrypt the shared secret we just invented + // above when we created the association. + using (DiffieHellman dh = new DiffieHellmanManaged( + 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, diffieHellmanRequest.DiffieHellmanConsumerPublic, association.SecretKey); + } + return association; + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateRequestProvider.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateRequestProvider.cs new file mode 100644 index 0000000..5da8307 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateRequestProvider.cs @@ -0,0 +1,94 @@ +namespace DotNetOpenAuth.OpenId.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + internal abstract class AssociateRequestProvider : AssociateRequest { + /// <summary> + /// Creates a Provider's response to an incoming association request. + /// </summary> + /// <param name="associationStore">The association store.</param> + /// <param name="securitySettings">The security settings on the Provider.</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(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { + Contract.Requires<ArgumentNullException>(associationStore != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); + + IProtocolMessage response; + if (securitySettings.IsAssociationInPermittedRange(Protocol, this.AssociationType) && + HmacShaAssociation.IsDHSessionCompatible(Protocol, this.AssociationType, this.SessionType)) { + response = this.CreateResponseCore(); + + // Create and store the association if this is a successful response. + var successResponse = response as AssociateSuccessfulResponse; + if (successResponse != null) { + successResponse.CreateAssociation(this, associationStore, securitySettings); + } + } else { + response = this.CreateUnsuccessfulResponse(securitySettings); + } + + 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(); + + /// <summary> + /// Creates a response that notifies the Relying Party that the requested + /// association type is not supported by this Provider, and offers + /// an alternative association type, if possible. + /// </summary> + /// <param name="securitySettings">The security settings that apply to this Provider.</param> + /// <returns>The response to send to the Relying Party.</returns> + private AssociateUnsuccessfulResponse CreateUnsuccessfulResponse(ProviderSecuritySettings securitySettings) { + Contract.Requires<ArgumentNullException>(securitySettings != null); + + var unsuccessfulResponse = new AssociateUnsuccessfulResponse(this.Version, this); + + // The strategy here is to suggest that the RP try again with the lowest + // permissible security settings, giving the RP the best chance of being + // able to match with a compatible request. + bool unencryptedAllowed = this.Recipient.IsTransportSecure(); + bool useDiffieHellman = !unencryptedAllowed; + string associationType, sessionType; + if (HmacShaAssociation.TryFindBestAssociation(Protocol, false, securitySettings, useDiffieHellman, out associationType, out sessionType)) { + ErrorUtilities.VerifyInternal(this.AssociationType != associationType, "The RP asked for an association that should have been allowed, but the OP is trying to suggest the same one as an alternative!"); + unsuccessfulResponse.AssociationType = associationType; + unsuccessfulResponse.SessionType = sessionType; + Logger.OpenId.InfoFormat( + "Association requested of type '{0}' and session '{1}', which the Provider does not support. Sending back suggested alternative of '{0}' with session '{1}'.", + this.AssociationType, + this.SessionType, + unsuccessfulResponse.AssociationType, + unsuccessfulResponse.SessionType); + } else { + Logger.OpenId.InfoFormat("Association requested of type '{0}' and session '{1}', which the Provider does not support. No alternative association type qualified for suggesting back to the Relying Party.", this.AssociationType, this.SessionType); + } + + return unsuccessfulResponse; + } + + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateSuccessfulResponseProvider.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateSuccessfulResponseProvider.cs new file mode 100644 index 0000000..3a71bba --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateSuccessfulResponseProvider.cs @@ -0,0 +1,27 @@ +namespace DotNetOpenAuth.OpenId.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.OpenId.Provider; + + internal abstract class AssociateSuccessfulResponseProvider : AssociateSuccessfulResponse { + /// <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> + /// <param name="associationStore">The Provider's association store.</param> + /// <param name="securitySettings">The security settings of the Provider.</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, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings); + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateSuccessfulResponseProviderContract.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateSuccessfulResponseProviderContract.cs new file mode 100644 index 0000000..9824316 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateSuccessfulResponseProviderContract.cs @@ -0,0 +1,18 @@ +namespace DotNetOpenAuth.OpenId.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Diagnostics.Contracts; + using DotNetOpenAuth.OpenId.Provider; + + [ContractClassFor(typeof(AssociateSuccessfulResponseProvider))] + internal abstract class AssociateSuccessfulResponseProviderContract : AssociateSuccessfulResponseProvider { + protected override Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { + Contract.Requires<ArgumentNullException>(request != null); + Contract.Requires<ArgumentNullException>(associationStore != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); + throw new NotImplementedException(); + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateUnencryptedResponseProvider.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateUnencryptedResponseProvider.cs new file mode 100644 index 0000000..c390a5e --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/AssociateUnencryptedResponseProvider.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------- +// <copyright file="AssociateUnencryptedResponseProvider.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.OpenId.Provider; + + internal class AssociateUnencryptedResponseProvider : AssociateUnencryptedResponse { + /// <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> + /// <param name="associationStore">The Provider's association store.</param> + /// <param name="securitySettings">The security settings of the Provider.</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> + /// </remarks> + protected override Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { + Association association = HmacShaAssociation.Create(Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings); + this.MacKey = association.SecretKey; + return association; + } + + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/CheckAuthenticationResponseProvider.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/CheckAuthenticationResponseProvider.cs new file mode 100644 index 0000000..3853693 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Messages/CheckAuthenticationResponseProvider.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace DotNetOpenAuth.OpenId.Messages { + class CheckAuthenticationResponseProvider : CheckAuthenticationResponse { + + /// <summary> + /// Initializes a new instance of the <see cref="CheckAuthenticationResponse"/> class + /// for use by the Provider. + /// </summary> + /// <param name="request">The request that this message is responding to.</param> + /// <param name="provider">The OpenID Provider that is preparing to send this response.</param> + internal CheckAuthenticationResponseProvider(CheckAuthenticationRequest request, OpenIdProvider provider) + : base(request.Version, request) { + Contract.Requires<ArgumentNullException>(provider != null); + + // The channel's binding elements have already set the request's IsValid property + // appropriately. We just copy it into the response message. + this.IsValid = request.IsValid; + + // Confirm the RP should invalidate the association handle only if the association + // is not valid (any longer). OpenID 2.0 section 11.4.2.2. + IndirectSignedResponse signedResponse = new IndirectSignedResponse(request, provider.Channel); + string invalidateHandle = ((ITamperResistantOpenIdMessage)signedResponse).InvalidateHandle; + if (!string.IsNullOrEmpty(invalidateHandle) && !provider.AssociationStore.IsValid(signedResponse, false, invalidateHandle)) { + this.InvalidateHandle = invalidateHandle; + } + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/OpenIdProviderUtilities.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/OpenIdProviderUtilities.cs new file mode 100644 index 0000000..680759b --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/OpenIdProviderUtilities.cs @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------- +// <copyright file="OpenIdProviderUtilities.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.OpenId.Provider; + using DotNetOpenAuth.Messaging; + using System.Diagnostics.Contracts; + using DotNetOpenAuth.OpenId.Messages; + + internal static class OpenIdProviderUtilities { + /// <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> + /// <param name="associationStore">The Provider's association store.</param> + /// <param name="securitySettings">The security settings for the Provider. Should be <c>null</c> for Relying Parties.</param> + /// <returns> + /// The created association. + /// </returns> + /// <remarks> + /// The response message is updated to include the details of the created association by this method. + /// This method is called by both the Provider and the Relying Party, but actually performs + /// quite different operations in either scenario. + /// </remarks> + internal static Association CreateAssociation(AssociateRequest request, AssociateSuccessfulResponse response, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { + Contract.Requires<ArgumentNullException>(request != null); + Contract.Requires<ArgumentNullException>(response != null, "response"); + Contract.Requires<ArgumentNullException>(securitySettings != null, "securitySettings"); + + // We need to initialize some common properties based on the created association. + var association = CreateAssociationAtProvider(request, associationStore, securitySettings); + response.ExpiresIn = association.SecondsTillExpiration; + response.AssociationHandle = association.Handle; + + return association; + } + + + /// <summary> + /// Determines whether the association with the specified handle is (still) valid. + /// </summary> + /// <param name="associationStore">The association store.</param> + /// <param name="containingMessage">The OpenID message that referenced this association handle.</param> + /// <param name="isPrivateAssociation">A value indicating whether a private association is expected.</param> + /// <param name="handle">The association handle.</param> + /// <returns> + /// <c>true</c> if the specified containing message is valid; otherwise, <c>false</c>. + /// </returns> + internal static bool IsValid(this IProviderAssociationStore associationStore, IProtocolMessage containingMessage, bool isPrivateAssociation, string handle) { + Contract.Requires<ArgumentNullException>(associationStore != null); + Contract.Requires<ArgumentNullException>(containingMessage != null); + Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(handle)); + try { + return associationStore.Deserialize(containingMessage, isPrivateAssociation, handle) != null; + } catch (ProtocolException) { + return false; + } + } + } +} diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AnonymousRequest.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AnonymousRequest.cs index 974d729..974d729 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AnonymousRequest.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AnonymousRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AnonymousRequestEventArgs.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AnonymousRequestEventArgs.cs index 9ffaa55..9ffaa55 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AnonymousRequestEventArgs.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AnonymousRequestEventArgs.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AssociationDataBag.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AssociationDataBag.cs index a8ac41e..a8ac41e 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AssociationDataBag.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AssociationDataBag.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AssociationRelyingPartyType.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AssociationRelyingPartyType.cs index 4d121b1..4d121b1 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AssociationRelyingPartyType.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AssociationRelyingPartyType.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AuthenticationChallengeEventArgs.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AuthenticationChallengeEventArgs.cs index 1594994..1594994 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AuthenticationChallengeEventArgs.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AuthenticationChallengeEventArgs.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AuthenticationRequest.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AuthenticationRequest.cs index d22f858..d22f858 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AuthenticationRequest.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AuthenticationRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AutoResponsiveRequest.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AutoResponsiveRequest.cs index 41e082b..41e082b 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/AutoResponsiveRequest.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AutoResponsiveRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/HostProcessedRequest.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/HostProcessedRequest.cs index ec0c58a..ec0c58a 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/HostProcessedRequest.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/HostProcessedRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IAnonymousRequest.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IAnonymousRequest.cs index ec2c175..ec2c175 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IAnonymousRequest.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IAnonymousRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IAuthenticationRequest.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IAuthenticationRequest.cs index f59d436..f59d436 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IAuthenticationRequest.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IAuthenticationRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IDirectedIdentityIdentifierProvider.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IDirectedIdentityIdentifierProvider.cs index 985bb54..985bb54 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IDirectedIdentityIdentifierProvider.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IDirectedIdentityIdentifierProvider.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IErrorReporting.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IErrorReporting.cs index 1c73595..1c73595 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IErrorReporting.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IErrorReporting.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IHostProcessedRequest.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IHostProcessedRequest.cs index 1c38d4b..1c38d4b 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IHostProcessedRequest.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IHostProcessedRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IProviderAssociationStore.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IProviderAssociationStore.cs index 5a554c1..5a554c1 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IProviderAssociationStore.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IProviderAssociationStore.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IProviderBehavior.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IProviderBehavior.cs index 01b4ac8..01b4ac8 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IProviderBehavior.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IProviderBehavior.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IRequest.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IRequest.cs index c231fa3..c231fa3 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IRequest.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IdentityEndpoint.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IdentityEndpoint.cs index 3a18b70..3a18b70 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IdentityEndpoint.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IdentityEndpoint.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IdentityEndpointNormalizationEventArgs.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IdentityEndpointNormalizationEventArgs.cs index d190792..d190792 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/IdentityEndpointNormalizationEventArgs.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/IdentityEndpointNormalizationEventArgs.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/OpenIdProvider.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/OpenIdProvider.cs index ea19202..ea19202 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/OpenIdProvider.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/OpenIdProvider.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs index 46e172c..46e172c 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/ProviderAssociationHandleEncoder.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/ProviderAssociationHandleEncoder.cs index 5de560c..5de560c 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/ProviderAssociationHandleEncoder.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/ProviderAssociationHandleEncoder.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/ProviderAssociationKeyStorage.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/ProviderAssociationKeyStorage.cs index 9801aac..9801aac 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/ProviderAssociationKeyStorage.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/ProviderAssociationKeyStorage.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/ProviderEndpoint.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/ProviderEndpoint.cs index 90dedc2..90dedc2 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/ProviderEndpoint.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/ProviderEndpoint.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/ProviderSecuritySettings.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/ProviderSecuritySettings.cs index 130e6dd..130e6dd 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/ProviderSecuritySettings.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/ProviderSecuritySettings.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/RelyingPartyDiscoveryResult.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/RelyingPartyDiscoveryResult.cs index 4eca6d6..4eca6d6 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/RelyingPartyDiscoveryResult.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/RelyingPartyDiscoveryResult.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/Request.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/Request.cs index 4e54ef9..4e54ef9 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/Request.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/Request.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/RequestContract.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/RequestContract.cs index dee140e..dee140e 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/RequestContract.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/RequestContract.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Provider/StandardProviderApplicationStore.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/StandardProviderApplicationStore.cs index b5880d3..b5880d3 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Provider/StandardProviderApplicationStore.cs +++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/StandardProviderApplicationStore.cs diff --git a/src/DotNetOpenAuth.OpenId/ComponentModel/IdentifierConverter.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/ComponentModel/IdentifierConverter.cs index 61c0fd8..523bd02 100644 --- a/src/DotNetOpenAuth.OpenId/ComponentModel/IdentifierConverter.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/ComponentModel/IdentifierConverter.cs @@ -10,7 +10,6 @@ namespace DotNetOpenAuth.ComponentModel { using System.ComponentModel.Design.Serialization; using System.Reflection; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// A design-time helper to give an OpenID Identifier property an auto-complete functionality diff --git a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdRelyingPartyElement.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/Configuration/OpenIdRelyingPartyElement.cs index 17b890f..c80141a 100644 --- a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdRelyingPartyElement.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/Configuration/OpenIdRelyingPartyElement.cs @@ -22,6 +22,11 @@ namespace DotNetOpenAuth.Configuration { private const string StoreConfigName = "store"; /// <summary> + /// The name of the <relyingParty> sub-element. + /// </summary> + private const string RelyingPartyElementName = "relyingParty"; + + /// <summary> /// The name of the attribute that specifies whether dnoa.userSuppliedIdentifier is tacked onto the openid.return_to URL. /// </summary> private const string PreserveUserSuppliedIdentifierConfigName = "preserveUserSuppliedIdentifier"; diff --git a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs index 225b1e7..225b1e7 100644 --- a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/DotNetOpenAuth.OpenId.RelyingParty.csproj b/src/DotNetOpenAuth.OpenId.RelyingParty/DotNetOpenAuth.OpenId.RelyingParty.csproj new file mode 100644 index 0000000..324da14 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/DotNetOpenAuth.OpenId.RelyingParty.csproj @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + </PropertyGroup> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.props" /> + <PropertyGroup> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>DotNetOpenAuth</RootNamespace> + <AssemblyName>DotNetOpenAuth.OpenId.RelyingParty</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + </PropertyGroup> + <ItemGroup> + <Compile Include="ComponentModel\IdentifierConverter.cs" /> + <Compile Include="Configuration\OpenIdRelyingPartyElement.cs" /> + <Compile Include="Configuration\OpenIdRelyingPartySecuritySettingsElement.cs" /> + <Compile Include="OpenId\Behaviors\AXFetchAsSregTransform.cs" /> + <Compile Include="OpenId\Behaviors\GsaIcamRelyingPartyProfile.cs" /> + <Compile Include="OpenId\ChannelElements\ExtensionsBindingElementRelyingParty.cs" /> + <Compile Include="OpenId\ChannelElements\OpenIdRelyingPartyChannel.cs" /> + <Compile Include="OpenId\ChannelElements\RelyingPartySecurityOptions.cs" /> + <Compile Include="OpenId\ChannelElements\RelyingPartySigningBindingElement.cs" /> + <Compile Include="OpenId\ChannelElements\ReturnToNonceBindingElement.cs" /> + <Compile Include="OpenId\Extensions\ExtensionsInteropRelyingPartyHelper.cs" /> + <Compile Include="OpenId\Extensions\UI\UIUtilities.cs" /> + <Compile Include="OpenId\HostMetaDiscoveryService.cs" /> + <Compile Include="OpenId\IdentifierDiscoveryResult.cs" /> + <Compile Include="OpenId\IIdentifierDiscoveryService.cs" /> + <Compile Include="OpenId\Interop\AuthenticationResponseShim.cs" /> + <Compile Include="OpenId\Interop\ClaimsResponseShim.cs" /> + <Compile Include="OpenId\Interop\OpenIdRelyingPartyShim.cs" /> + <Compile Include="OpenId\Messages\AssociateDiffieHellmanResponse.cs" /> + <Compile Include="OpenId\Messages\AssociateRequestRelyingParty.cs" /> + <Compile Include="OpenId\Messages\AssociateSuccessfulResponseContract.cs" /> + <Compile Include="OpenId\Messages\AssociateSuccessfulResponseRelyingParty.cs" /> + <Compile Include="OpenId\Messages\AssociateUnencryptedResponseRelyingParty.cs" /> + <Compile Include="OpenId\Mvc\OpenIdAjaxOptions.cs" /> + <Compile Include="OpenId\Mvc\OpenIdHelper.cs" /> + <Compile Include="OpenId\OpenIdXrdsHelper.cs" /> + <Compile Include="OpenId\ProviderEndpointDescription.cs" /> + <Compile Include="OpenId\RelyingParty\CryptoKeyStoreAsRelyingPartyAssociationStore.cs" /> + <Compile Include="OpenId\RelyingParty\IRelyingPartyAssociationStore.cs" /> + <Compile Include="OpenId\RelyingParty\Associations.cs" /> + <Compile Include="OpenId\RelyingParty\AssociationManager.cs" /> + <Compile Include="OpenId\RelyingParty\AssociationPreference.cs" /> + <Compile Include="OpenId\RelyingParty\AuthenticationRequest.cs" /> + <Compile Include="OpenId\RelyingParty\DuplicateRequestedHostsComparer.cs" /> + <Compile Include="OpenId\RelyingParty\IProviderEndpoint.cs" /> + <Compile Include="OpenId\RelyingParty\IRelyingPartyBehavior.cs" /> + <Compile Include="OpenId\RelyingParty\IAuthenticationRequestContract.cs" /> + <Compile Include="OpenId\RelyingParty\NegativeAuthenticationResponse.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdAjaxRelyingParty.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdAjaxTextBox.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdButton.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdEventArgs.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdLogin.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdMobileTextBox.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdSelector.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdTextBox.cs" /> + <Compile Include="OpenId\RelyingParty\PopupBehavior.cs" /> + <Compile Include="OpenId\RelyingParty\PositiveAnonymousResponse.cs" /> + <Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponse.cs" /> + <Compile Include="OpenId\RelyingParty\AuthenticationStatus.cs" /> + <Compile Include="OpenId\RelyingParty\FailedAuthenticationResponse.cs" /> + <Compile Include="OpenId\RelyingParty\IAuthenticationRequest.cs" /> + <Compile Include="OpenId\RelyingParty\IAuthenticationResponse.cs" /> + <Compile Include="OpenId\RelyingParty\ISetupRequiredAuthenticationResponse.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdRelyingParty.cs" /> + <Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponseSnapshot.cs" /> + <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettings.cs" /> + <Compile Include="OpenId\RelyingParty\SelectorButton.cs" /> + <Compile Include="OpenId\RelyingParty\SelectorButtonContract.cs" /> + <Compile Include="OpenId\RelyingParty\SelectorOpenIdButton.cs" /> + <Compile Include="OpenId\RelyingParty\SelectorProviderButton.cs" /> + <Compile Include="OpenId\RelyingParty\SimpleXrdsProviderEndpoint.cs" /> + <Compile Include="OpenId\RelyingParty\StandardRelyingPartyApplicationStore.cs" /> + <Compile Include="OpenId\RelyingParty\WellKnownProviders.cs" /> + <Compile Include="OpenId\UriDiscoveryService.cs" /> + <Compile Include="OpenId\XriDiscoveryProxyService.cs" /> + </ItemGroup> + <ItemGroup> + <Content Include="OpenId\RelyingParty\login_failure.png" /> + <Content Include="OpenId\RelyingParty\login_success %28lock%29.png" /> + <Content Include="OpenId\RelyingParty\login_success.png" /> + <Content Include="OpenId\RelyingParty\OpenIdAjaxTextBox.css" /> + <Content Include="OpenId\RelyingParty\OpenIdAjaxTextBox.js" /> + <Content Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.js" /> + <Content Include="OpenId\RelyingParty\OpenIdRelyingPartyControlBase.js" /> + <Content Include="OpenId\RelyingParty\OpenIdSelector.css" /> + <Content Include="OpenId\RelyingParty\OpenIdSelector.js" /> + <Content Include="OpenId\RelyingParty\openid_login.png" /> + <Content Include="OpenId\RelyingParty\spinner.gif" /> + </ItemGroup> + <ItemGroup> + <None Include="OpenId\RelyingParty\Controls.cd" /> + <None Include="OpenId\RelyingParty\OpenIdRelyingParty.cd" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\DotNetOpenAuth.Messaging\DotNetOpenAuth.Messaging.csproj"> + <Project>{60426312-6AE5-4835-8667-37EDEA670222}</Project> + <Name>DotNetOpenAuth.Messaging</Name> + </ProjectReference> + <ProjectReference Include="..\DotNetOpenAuth.OpenId\DotNetOpenAuth.OpenId.csproj"> + <Project>{3896A32A-E876-4C23-B9B8-78E17D134CD3}</Project> + <Name>DotNetOpenAuth.OpenId</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" /> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " /> +</Project>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Behaviors/AXFetchAsSregTransform.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Behaviors/AXFetchAsSregTransform.cs new file mode 100644 index 0000000..70dbe64 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Behaviors/AXFetchAsSregTransform.cs @@ -0,0 +1,75 @@ +//----------------------------------------------------------------------- +// <copyright file="AXFetchAsSregTransform.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Behaviors { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Extensions; + using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + using DotNetOpenAuth.OpenId.Provider; + using DotNetOpenAuth.OpenId.RelyingParty; + + /// <summary> + /// An Attribute Exchange and Simple Registration filter to make all incoming attribute + /// requests look like Simple Registration requests, and to convert the response + /// to the originally requested extension and format. + /// </summary> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Abbreviation")] + public sealed class AXFetchAsSregRelyingPartyTransform : AXFetchAsSregTransform, IRelyingPartyBehavior { + /// <summary> + /// Initializes a new instance of the <see cref="AXFetchAsSregRelyingPartyTransform"/> class. + /// </summary> + public AXFetchAsSregRelyingPartyTransform() { + } + + #region IRelyingPartyBehavior Members + + /// <summary> + /// Applies a well known set of security requirements to a default set of security settings. + /// </summary> + /// <param name="securitySettings">The security settings to enhance with the requirements of this profile.</param> + /// <remarks> + /// Care should be taken to never decrease security when applying a profile. + /// Profiles should only enhance security requirements to avoid being + /// incompatible with each other. + /// </remarks> + void IRelyingPartyBehavior.ApplySecuritySettings(RelyingPartySecuritySettings securitySettings) { + } + + /// <summary> + /// Called when an authentication request is about to be sent. + /// </summary> + /// <param name="request">The request.</param> + /// <remarks> + /// Implementations should be prepared to be called multiple times on the same outgoing message + /// without malfunctioning. + /// </remarks> + void IRelyingPartyBehavior.OnOutgoingAuthenticationRequest(RelyingParty.IAuthenticationRequest request) { + // Don't create AX extensions for OpenID 1.x messages, since AX requires OpenID 2.0. + if (request.Provider.Version.Major >= 2) { + request.SpreadSregToAX(AXFormats); + } + } + + /// <summary> + /// Called when an incoming positive assertion is received. + /// </summary> + /// <param name="assertion">The positive assertion.</param> + void IRelyingPartyBehavior.OnIncomingPositiveAssertion(IAuthenticationResponse assertion) { + if (assertion.GetExtension<ClaimsResponse>() == null) { + ClaimsResponse sreg = assertion.UnifyExtensionsAsSreg(true); + ((PositiveAnonymousResponse)assertion).Response.Extensions.Add(sreg); + } + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Behaviors/GsaIcamRelyingPartyProfile.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Behaviors/GsaIcamRelyingPartyProfile.cs new file mode 100644 index 0000000..e8532b2 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Behaviors/GsaIcamRelyingPartyProfile.cs @@ -0,0 +1,123 @@ +//----------------------------------------------------------------------- +// <copyright file="GsaIcamRelyingPartyProfile.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Behaviors { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Linq; + using DotNetOpenAuth.Configuration; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; + using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + using DotNetOpenAuth.OpenId.RelyingParty; + + /// <summary> + /// Implements the Identity, Credential, & Access Management (ICAM) OpenID 2.0 Profile + /// for the General Services Administration (GSA). + /// </summary> + /// <remarks> + /// <para>Relying parties that include this profile are always held to the terms required by the profile, + /// but Providers are only affected by the special behaviors of the profile when the RP specifically + /// indicates that they want to use this profile. </para> + /// </remarks> + [Serializable] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Icam", Justification = "Acronym")] + public sealed class GsaIcamRelyingPartyProfile : GsaIcamProfile, IRelyingPartyBehavior { + /// <summary> + /// Initializes a new instance of the <see cref="GsaIcamRelyingPartyProfile"/> class. + /// </summary> + public GsaIcamRelyingPartyProfile() { + if (DisableSslRequirement) { + Logger.OpenId.Warn("GSA level 1 behavior has its RequireSsl requirement disabled."); + } + } + + #region IRelyingPartyBehavior Members + + /// <summary> + /// Applies a well known set of security requirements. + /// </summary> + /// <param name="securitySettings">The security settings to enhance with the requirements of this profile.</param> + /// <remarks> + /// Care should be taken to never decrease security when applying a profile. + /// Profiles should only enhance security requirements to avoid being + /// incompatible with each other. + /// </remarks> + void IRelyingPartyBehavior.ApplySecuritySettings(RelyingPartySecuritySettings securitySettings) { + if (securitySettings.MaximumHashBitLength < 256) { + securitySettings.MaximumHashBitLength = 256; + } + + securitySettings.RequireSsl = !DisableSslRequirement; + securitySettings.RequireDirectedIdentity = true; + securitySettings.RequireAssociation = true; + securitySettings.RejectDelegatingIdentifiers = true; + securitySettings.IgnoreUnsignedExtensions = true; + securitySettings.MinimumRequiredOpenIdVersion = ProtocolVersion.V20; + } + + /// <summary> + /// Called when an authentication request is about to be sent. + /// </summary> + /// <param name="request">The request.</param> + void IRelyingPartyBehavior.OnOutgoingAuthenticationRequest(RelyingParty.IAuthenticationRequest request) { + RelyingParty.AuthenticationRequest requestInternal = (RelyingParty.AuthenticationRequest)request; + ErrorUtilities.VerifyProtocol(string.Equals(request.Realm.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal) || DisableSslRequirement, BehaviorStrings.RealmMustBeHttps); + + var pape = requestInternal.AppliedExtensions.OfType<PolicyRequest>().SingleOrDefault(); + if (pape == null) { + request.AddExtension(pape = new PolicyRequest()); + } + + if (!pape.PreferredPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { + pape.PreferredPolicies.Add(AuthenticationPolicies.PrivatePersonalIdentifier); + } + + if (!pape.PreferredPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1)) { + pape.PreferredPolicies.Add(AuthenticationPolicies.USGovernmentTrustLevel1); + } + + if (!AllowPersonallyIdentifiableInformation && !pape.PreferredPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { + pape.PreferredPolicies.Add(AuthenticationPolicies.NoPersonallyIdentifiableInformation); + } + + if (pape.PreferredPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { + ErrorUtilities.VerifyProtocol( + (!requestInternal.AppliedExtensions.OfType<ClaimsRequest>().Any() && + !requestInternal.AppliedExtensions.OfType<FetchRequest>().Any()), + BehaviorStrings.PiiIncludedWithNoPiiPolicy); + } + + Reporting.RecordEventOccurrence(this, "RP"); + } + + /// <summary> + /// Called when an incoming positive assertion is received. + /// </summary> + /// <param name="assertion">The positive assertion.</param> + void IRelyingPartyBehavior.OnIncomingPositiveAssertion(IAuthenticationResponse assertion) { + PolicyResponse pape = assertion.GetExtension<PolicyResponse>(); + ErrorUtilities.VerifyProtocol( + pape != null && + pape.ActualPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1) && + pape.ActualPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier), + BehaviorStrings.PapeResponseOrRequiredPoliciesMissing); + + ErrorUtilities.VerifyProtocol(AllowPersonallyIdentifiableInformation || pape.ActualPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation), BehaviorStrings.PapeResponseOrRequiredPoliciesMissing); + + if (pape.ActualPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { + ErrorUtilities.VerifyProtocol( + assertion.GetExtension<ClaimsResponse>() == null && + assertion.GetExtension<FetchResponse>() == null, + BehaviorStrings.PiiIncludedWithNoPiiPolicy); + } + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/ExtensionsBindingElementRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/ExtensionsBindingElementRelyingParty.cs new file mode 100644 index 0000000..f6f6707 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/ExtensionsBindingElementRelyingParty.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics.Contracts; +using DotNetOpenAuth.OpenId.RelyingParty; + +namespace DotNetOpenAuth.OpenId.ChannelElements { + internal class ExtensionsBindingElementRelyingParty : ExtensionsBindingElement { + /// <summary> + /// The security settings that apply to this relying party, if it is a relying party. + /// </summary> + private readonly RelyingPartySecuritySettings relyingPartySecuritySettings; + + /// <summary> + /// Initializes a new instance of the <see cref="ExtensionsBindingElement"/> class. + /// </summary> + /// <param name="extensionFactory">The extension factory.</param> + /// <param name="securitySettings">The security settings.</param> + internal ExtensionsBindingElementRelyingParty(IOpenIdExtensionFactory extensionFactory, RelyingPartySecuritySettings securitySettings) + : base(extensionFactory, securitySettings, !securitySettings.IgnoreUnsignedExtensions) { + Contract.Requires<ArgumentNullException>(extensionFactory != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); + + this.relyingPartySecuritySettings = securitySettings; + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/OpenIdRelyingPartyChannel.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/OpenIdRelyingPartyChannel.cs new file mode 100644 index 0000000..585dbcd --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/OpenIdRelyingPartyChannel.cs @@ -0,0 +1,119 @@ +//----------------------------------------------------------------------- +// <copyright file="OpenIdRelyingPartyChannel.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.ChannelElements { + using System; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Bindings; + using DotNetOpenAuth.OpenId.Extensions; + using DotNetOpenAuth.OpenId.RelyingParty; + + internal class OpenIdRelyingPartyChannel : OpenIdChannel { + /// <summary> + /// Initializes a new instance of the <see cref="OpenIdChannel"/> class + /// for use by a Relying Party. + /// </summary> + /// <param name="cryptoKeyStore">The association store to use.</param> + /// <param name="nonceStore">The nonce store to use.</param> + /// <param name="securitySettings">The security settings to apply.</param> + internal OpenIdRelyingPartyChannel(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore, RelyingPartySecuritySettings securitySettings) + : this(cryptoKeyStore, nonceStore, new OpenIdMessageFactory(), securitySettings, false) { + Contract.Requires<ArgumentNullException>(securitySettings != null); + } + + /// <summary> + /// Initializes a new instance of the <see cref="OpenIdChannel"/> class + /// for use by a Relying Party. + /// </summary> + /// <param name="cryptoKeyStore">The association store to use.</param> + /// <param name="nonceStore">The nonce store to use.</param> + /// <param name="messageTypeProvider">An object that knows how to distinguish the various OpenID message types for deserialization purposes.</param> + /// <param name="securitySettings">The security settings to apply.</param> + /// <param name="nonVerifying">A value indicating whether the channel is set up with no functional security binding elements.</param> + private OpenIdRelyingPartyChannel(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, RelyingPartySecuritySettings securitySettings, bool nonVerifying) : + this(messageTypeProvider, InitializeBindingElements(cryptoKeyStore, nonceStore, securitySettings, nonVerifying)) { + Contract.Requires<ArgumentNullException>(messageTypeProvider != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); + Contract.Requires<ArgumentException>(!nonVerifying || securitySettings is RelyingPartySecuritySettings); + } + + /// <summary> + /// A value indicating whether the channel is set up + /// with no functional security binding elements. + /// </summary> + /// <returns>A new <see cref="OpenIdChannel"/> instance that will not perform verification on incoming messages or apply any security to outgoing messages.</returns> + /// <remarks> + /// <para>A value of <c>true</c> allows the relying party to preview incoming + /// messages without invalidating nonces or checking signatures.</para> + /// <para>Setting this to <c>true</c> poses a great security risk and is only + /// present to support the <see cref="OpenIdAjaxTextBox"/> which needs to preview + /// messages, and will validate them later.</para> + /// </remarks> + internal static OpenIdChannel CreateNonVerifyingChannel() { + Contract.Ensures(Contract.Result<OpenIdChannel>() != null); + + return new OpenIdRelyingPartyChannel(null, null, new OpenIdMessageFactory(), new RelyingPartySecuritySettings(), true); + } + + /// <summary> + /// Initializes the binding elements. + /// </summary> + /// <param name="cryptoKeyStore">The crypto key store.</param> + /// <param name="nonceStore">The nonce store to use.</param> + /// <param name="securitySettings">The security settings to apply. Must be an instance of either <see cref="RelyingPartySecuritySettings"/> or <see cref="ProviderSecuritySettings"/>.</param> + /// <param name="nonVerifying">A value indicating whether the channel is set up with no functional security binding elements.</param> + /// <returns> + /// An array of binding elements which may be used to construct the channel. + /// </returns> + private static IChannelBindingElement[] InitializeBindingElements(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore, RelyingPartySecuritySettings securitySettings, bool nonVerifying) { + Contract.Requires<ArgumentNullException>(securitySettings != null); + + SigningBindingElement signingElement; + signingElement = nonVerifying ? null : new SigningBindingElement(new CryptoKeyStoreAsRelyingPartyAssociationStore(cryptoKeyStore ?? new MemoryCryptoKeyStore())); + + var extensionFactory = OpenIdExtensionFactoryAggregator.LoadFromConfiguration(); + + List<IChannelBindingElement> elements = new List<IChannelBindingElement>(8); + elements.Add(new ExtensionsBindingElement(extensionFactory, securitySettings)); + elements.Add(new RelyingPartySecurityOptions(securitySettings)); + elements.Add(new BackwardCompatibilityBindingElement()); + ReturnToNonceBindingElement requestNonceElement = null; + + if (cryptoKeyStore != null) { + if (nonceStore != null) { + // There is no point in having a ReturnToNonceBindingElement without + // a ReturnToSignatureBindingElement because the nonce could be + // artificially changed without it. + requestNonceElement = new ReturnToNonceBindingElement(nonceStore, securitySettings); + elements.Add(requestNonceElement); + } + + // It is important that the return_to signing element comes last + // so that the nonce is included in the signature. + elements.Add(new ReturnToSignatureBindingElement(cryptoKeyStore)); + } + + ErrorUtilities.VerifyOperation(!securitySettings.RejectUnsolicitedAssertions || requestNonceElement != null, OpenIdStrings.UnsolicitedAssertionRejectionRequiresNonceStore); + + if (nonVerifying) { + elements.Add(new SkipSecurityBindingElement()); + } else { + if (nonceStore != null) { + elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true)); + } + + elements.Add(new StandardExpirationBindingElement()); + elements.Add(signingElement); + } + + return elements.ToArray(); + } + } +} diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/RelyingPartySecurityOptions.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/RelyingPartySecurityOptions.cs index d8fc103..d8fc103 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/RelyingPartySecurityOptions.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/RelyingPartySecurityOptions.cs diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/RelyingPartySigningBindingElement.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/RelyingPartySigningBindingElement.cs new file mode 100644 index 0000000..1d86152 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/RelyingPartySigningBindingElement.cs @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------- +// <copyright file="RelyingPartySigningBindingElement.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.ChannelElements { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.OpenId.RelyingParty; + using DotNetOpenAuth.OpenId.Messages; + using System.Diagnostics.Contracts; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Bindings; + + internal class RelyingPartySigningBindingElement : SigningBindingElement { + /// <summary> + /// The association store used by Relying Parties to look up the secrets needed for signing. + /// </summary> + private readonly IRelyingPartyAssociationStore rpAssociations; + + /// <summary> + /// Initializes a new instance of the SigningBindingElement class for use by a Relying Party. + /// </summary> + /// <param name="associationStore">The association store used to look up the secrets needed for signing. May be null for dumb Relying Parties.</param> + internal RelyingPartySigningBindingElement(IRelyingPartyAssociationStore associationStore) { + this.rpAssociations = associationStore; + } + + protected override Association GetSpecificAssociation(ITamperResistantOpenIdMessage signedMessage) { + Association association = null; + + if (!string.IsNullOrEmpty(signedMessage.AssociationHandle)) { + IndirectSignedResponse indirectSignedMessage = signedMessage as IndirectSignedResponse; + if (this.rpAssociations != null) { // if on a smart RP + Uri providerEndpoint = indirectSignedMessage.ProviderEndpoint; + association = this.rpAssociations.GetAssociation(providerEndpoint, signedMessage.AssociationHandle); + } + } + + return association; + } + + protected override Association GetAssociation(ITamperResistantOpenIdMessage signedMessage) { + Contract.Requires<ArgumentNullException>(signedMessage != null); + + // We're on a Relying Party verifying a signature. + IDirectedProtocolMessage directedMessage = (IDirectedProtocolMessage)signedMessage; + if (this.rpAssociations != null) { + return this.rpAssociations.GetAssociation(directedMessage.Recipient, signedMessage.AssociationHandle); + } else { + return null; + } + } + + protected override MessageProtections VerifySignatureByUnrecognizedHandle(IProtocolMessage message, ITamperResistantOpenIdMessage signedMessage, MessageProtections protectionsApplied) { + // We did not recognize the association the provider used to sign the message. + // Ask the provider to check the signature then. + var indirectSignedResponse = (IndirectSignedResponse)signedMessage; + var checkSignatureRequest = new CheckAuthenticationRequest(indirectSignedResponse, this.Channel); + var checkSignatureResponse = this.Channel.Request<CheckAuthenticationResponse>(checkSignatureRequest); + if (!checkSignatureResponse.IsValid) { + Logger.Bindings.Error("Provider reports signature verification failed."); + throw new InvalidSignatureException(message); + } + + // If the OP confirms that a handle should be invalidated as well, do that. + if (!string.IsNullOrEmpty(checkSignatureResponse.InvalidateHandle)) { + if (this.rpAssociations != null) { + this.rpAssociations.RemoveAssociation(indirectSignedResponse.ProviderEndpoint, checkSignatureResponse.InvalidateHandle); + } + } + + // When we're in dumb mode we can't provide our own replay protection, + // but for OpenID 2.0 Providers we can rely on them providing it as part + // of signature verification. + if (message.Version.Major >= 2) { + protectionsApplied |= MessageProtections.ReplayProtection; + } + + return protectionsApplied; + } + } +} diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToNonceBindingElement.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/ReturnToNonceBindingElement.cs index 3649543..3649543 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToNonceBindingElement.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/ReturnToNonceBindingElement.cs diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Extensions/ExtensionsInteropRelyingPartyHelper.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Extensions/ExtensionsInteropRelyingPartyHelper.cs new file mode 100644 index 0000000..a864da8 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Extensions/ExtensionsInteropRelyingPartyHelper.cs @@ -0,0 +1,151 @@ +//----------------------------------------------------------------------- +// <copyright file="ExtensionsInteropRelyingPartyHelper.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Extensions { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Linq; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + using DotNetOpenAuth.OpenId.Messages; + + /// <summary> + /// A set of methods designed to assist in improving interop across different + /// OpenID implementations and their extensions. + /// </summary> + public static class ExtensionsInteropRelyingPartyHelper : ExtensionsInteropHelper { + /// <summary> + /// Adds an Attribute Exchange (AX) extension to the authentication request + /// that asks for the same attributes as the Simple Registration (sreg) extension + /// that is already applied. + /// </summary> + /// <param name="request">The authentication request.</param> + /// <param name="attributeFormats">The attribute formats to use in the AX request.</param> + /// <remarks> + /// <para>If discovery on the user-supplied identifier yields hints regarding which + /// extensions and attribute formats the Provider supports, this method MAY ignore the + /// <paramref name="attributeFormats"/> argument and accomodate the Provider to minimize + /// the size of the request.</para> + /// <para>If the request does not carry an sreg extension, the method logs a warning but + /// otherwise quietly returns doing nothing.</para> + /// </remarks> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Abbreviation")] + public static void SpreadSregToAX(this RelyingParty.IAuthenticationRequest request, AXAttributeFormats attributeFormats) { + Contract.Requires<ArgumentNullException>(request != null); + + var req = (RelyingParty.AuthenticationRequest)request; + var sreg = req.AppliedExtensions.OfType<ClaimsRequest>().SingleOrDefault(); + if (sreg == null) { + Logger.OpenId.Debug("No Simple Registration (ClaimsRequest) extension present in the request to spread to AX."); + return; + } + + if (req.DiscoveryResult.IsExtensionSupported<ClaimsRequest>()) { + Logger.OpenId.Debug("Skipping generation of AX request because the Identifier advertises the Provider supports the Sreg extension."); + return; + } + + var ax = req.AppliedExtensions.OfType<FetchRequest>().SingleOrDefault(); + if (ax == null) { + ax = new FetchRequest(); + req.AddExtension(ax); + } + + // Try to use just one AX Type URI format if we can figure out which type the OP accepts. + AXAttributeFormats detectedFormat; + if (TryDetectOPAttributeFormat(request, out detectedFormat)) { + Logger.OpenId.Debug("Detected OP support for AX but not for Sreg. Removing Sreg extension request and using AX instead."); + attributeFormats = detectedFormat; + req.Extensions.Remove(sreg); + } else { + Logger.OpenId.Debug("Could not determine whether OP supported Sreg or AX. Using both extensions."); + } + + foreach (AXAttributeFormats format in ExtensionsInteropHelper.ForEachFormat(attributeFormats)) { + ExtensionsInteropHelper.FetchAttribute(ax, format, WellKnownAttributes.BirthDate.WholeBirthDate, sreg.BirthDate); + ExtensionsInteropHelper.FetchAttribute(ax, format, WellKnownAttributes.Contact.HomeAddress.Country, sreg.Country); + ExtensionsInteropHelper.FetchAttribute(ax, format, WellKnownAttributes.Contact.Email, sreg.Email); + ExtensionsInteropHelper.FetchAttribute(ax, format, WellKnownAttributes.Name.FullName, sreg.FullName); + ExtensionsInteropHelper.FetchAttribute(ax, format, WellKnownAttributes.Person.Gender, sreg.Gender); + ExtensionsInteropHelper.FetchAttribute(ax, format, WellKnownAttributes.Preferences.Language, sreg.Language); + ExtensionsInteropHelper.FetchAttribute(ax, format, WellKnownAttributes.Name.Alias, sreg.Nickname); + ExtensionsInteropHelper.FetchAttribute(ax, format, WellKnownAttributes.Contact.HomeAddress.PostalCode, sreg.PostalCode); + ExtensionsInteropHelper.FetchAttribute(ax, format, WellKnownAttributes.Preferences.TimeZone, sreg.TimeZone); + } + } + + /// <summary> + /// Looks for Simple Registration and Attribute Exchange (all known formats) + /// response extensions and returns them as a Simple Registration extension. + /// </summary> + /// <param name="response">The authentication response.</param> + /// <param name="allowUnsigned">if set to <c>true</c> unsigned extensions will be included in the search.</param> + /// <returns> + /// The Simple Registration response if found, + /// or a fabricated one based on the Attribute Exchange extension if found, + /// or just an empty <see cref="ClaimsResponse"/> if there was no data. + /// Never <c>null</c>.</returns> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Abbreviation")] + public static ClaimsResponse UnifyExtensionsAsSreg(this RelyingParty.IAuthenticationResponse response, bool allowUnsigned) { + Contract.Requires<ArgumentNullException>(response != null); + + var resp = (RelyingParty.IAuthenticationResponse)response; + var sreg = allowUnsigned ? resp.GetUntrustedExtension<ClaimsResponse>() : resp.GetExtension<ClaimsResponse>(); + if (sreg != null) { + return sreg; + } + + AXAttributeFormats formats = AXAttributeFormats.All; + sreg = new ClaimsResponse(); + var fetchResponse = allowUnsigned ? resp.GetUntrustedExtension<FetchResponse>() : resp.GetExtension<FetchResponse>(); + if (fetchResponse != null) { + ((IOpenIdMessageExtension)sreg).IsSignedByRemoteParty = fetchResponse.IsSignedByProvider; + sreg.BirthDateRaw = fetchResponse.GetAttributeValue(WellKnownAttributes.BirthDate.WholeBirthDate, formats); + sreg.Country = fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.HomeAddress.Country, formats); + sreg.PostalCode = fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.HomeAddress.PostalCode, formats); + sreg.Email = fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.Email, formats); + sreg.FullName = fetchResponse.GetAttributeValue(WellKnownAttributes.Name.FullName, formats); + sreg.Language = fetchResponse.GetAttributeValue(WellKnownAttributes.Preferences.Language, formats); + sreg.Nickname = fetchResponse.GetAttributeValue(WellKnownAttributes.Name.Alias, formats); + sreg.TimeZone = fetchResponse.GetAttributeValue(WellKnownAttributes.Preferences.TimeZone, formats); + string gender = fetchResponse.GetAttributeValue(WellKnownAttributes.Person.Gender, formats); + if (gender != null) { + sreg.Gender = (Gender)ExtensionsInteropHelper.genderEncoder.Decode(gender); + } + } + + return sreg; + } + + /// <summary> + /// Gets the attribute value if available. + /// </summary> + /// <param name="fetchResponse">The AX fetch response extension to look for the attribute value.</param> + /// <param name="typeUri">The type URI of the attribute, using the axschema.org format of <see cref="WellKnownAttributes"/>.</param> + /// <param name="formats">The AX type URI formats to search.</param> + /// <returns> + /// The first value of the attribute, if available. + /// </returns> + internal static string GetAttributeValue(this FetchResponse fetchResponse, string typeUri, AXAttributeFormats formats) { + return ExtensionsInteropHelper.ForEachFormat(formats).Select(format => fetchResponse.GetAttributeValue(ExtensionsInteropHelper.TransformAXFormat(typeUri, format))).FirstOrDefault(s => s != null); + } + + /// <summary> + /// Tries to find the exact format of AX attribute Type URI supported by the Provider. + /// </summary> + /// <param name="request">The authentication request.</param> + /// <param name="attributeFormat">The attribute formats the RP will try if this discovery fails.</param> + /// <returns>The AX format(s) to use based on the Provider's advertised AX support.</returns> + private static bool TryDetectOPAttributeFormat(RelyingParty.IAuthenticationRequest request, out AXAttributeFormats attributeFormat) { + Contract.Requires<ArgumentNullException>(request != null); + attributeFormat = ExtensionsInteropHelper.DetectAXFormat(request.DiscoveryResult.Capabilities); + return attributeFormat != AXAttributeFormats.None; + } + } +} diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/UI/UIUtilities.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Extensions/UI/UIUtilities.cs index cee6882..cee6882 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/UI/UIUtilities.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Extensions/UI/UIUtilities.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/HostMetaDiscoveryService.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/HostMetaDiscoveryService.cs index 215ea24..215ea24 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/HostMetaDiscoveryService.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/HostMetaDiscoveryService.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/IIdentifierDiscoveryService.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/IIdentifierDiscoveryService.cs index fcea327..fcea327 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/IIdentifierDiscoveryService.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/IIdentifierDiscoveryService.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/IdentifierDiscoveryResult.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/IdentifierDiscoveryResult.cs index c851f24..c851f24 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/IdentifierDiscoveryResult.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/IdentifierDiscoveryResult.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Interop/AuthenticationResponseShim.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Interop/AuthenticationResponseShim.cs index c0354ac..c0354ac 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Interop/AuthenticationResponseShim.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Interop/AuthenticationResponseShim.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Interop/ClaimsResponseShim.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Interop/ClaimsResponseShim.cs index 689777b..689777b 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Interop/ClaimsResponseShim.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Interop/ClaimsResponseShim.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Interop/OpenIdRelyingPartyShim.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Interop/OpenIdRelyingPartyShim.cs index fc0f32e..fc0f32e 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Interop/OpenIdRelyingPartyShim.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Interop/OpenIdRelyingPartyShim.cs diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateDiffieHellmanResponse.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateDiffieHellmanResponse.cs new file mode 100644 index 0000000..de3dad8 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateDiffieHellmanResponse.cs @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------- +// <copyright file="AssociateDiffieHellmanRelyingPartyResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Messages { + using System; + using System.Diagnostics.Contracts; + using System.Security.Cryptography; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Reflection; + using DotNetOpenAuth.OpenId.Provider; + using Org.Mentalis.Security.Cryptography; + + /// <summary> + /// The successful Diffie-Hellman association response message. + /// </summary> + /// <remarks> + /// Association response messages are described in OpenID 2.0 section 8.2. This type covers section 8.2.3. + /// </remarks> + internal class AssociateDiffieHellmanRelyingPartyResponse : AssociateDiffieHellmanResponse { + /// <summary> + /// Initializes a new instance of the <see cref="AssociateDiffieHellmanRelyingPartyResponse"/> class. + /// </summary> + /// <param name="responseVersion">The OpenID version of the response message.</param> + /// <param name="originatingRequest">The originating request.</param> + internal AssociateDiffieHellmanRelyingPartyResponse(Version responseVersion, AssociateDiffieHellmanRequest originatingRequest) + : base(responseVersion, originatingRequest) { + } + + /// <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> + /// <returns>The newly created association.</returns> + /// <remarks> + /// The resulting association is <i>not</i> added to the association store and must be done by the caller. + /// </remarks> + protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { + var diffieHellmanRequest = request as AssociateDiffieHellmanRequest; + ErrorUtilities.VerifyArgument(diffieHellmanRequest != null, OpenIdStrings.DiffieHellmanAssociationRequired); + + HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(Protocol, this.SessionType); + 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; + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateRequestRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateRequestRelyingParty.cs new file mode 100644 index 0000000..19d3a94 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateRequestRelyingParty.cs @@ -0,0 +1,70 @@ +namespace DotNetOpenAuth.OpenId.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Diagnostics.Contracts; + using DotNetOpenAuth.OpenId.RelyingParty; + + internal abstract class AssociateRequestRelyingParty : AssociateRequest { + /// <summary> + /// Creates an association request message that is appropriate for a given Provider. + /// </summary> + /// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param> + /// <param name="provider">The provider to create an association with.</param> + /// <returns> + /// The message to send to the Provider to request an association. + /// Null if no association could be created that meet the security requirements + /// and the provider OpenID version. + /// </returns> + internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider) { + Contract.Requires<ArgumentNullException>(securityRequirements != null); + Contract.Requires<ArgumentNullException>(provider != null); + + // Apply our knowledge of the endpoint's transport, OpenID version, and + // security requirements to decide the best association. + bool unencryptedAllowed = provider.Uri.IsTransportSecure(); + bool useDiffieHellman = !unencryptedAllowed; + string associationType, sessionType; + if (!HmacShaAssociation.TryFindBestAssociation(Protocol.Lookup(provider.Version), true, securityRequirements, useDiffieHellman, out associationType, out sessionType)) { + // There are no associations that meet all requirements. + Logger.OpenId.Warn("Security requirements and protocol combination knock out all possible association types. Dumb mode forced."); + return null; + } + + return Create(securityRequirements, provider, associationType, sessionType); + } + + /// <summary> + /// Creates an association request message that is appropriate for a given Provider. + /// </summary> + /// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param> + /// <param name="provider">The provider to create an association with.</param> + /// <param name="associationType">Type of the association.</param> + /// <param name="sessionType">Type of the session.</param> + /// <returns> + /// The message to send to the Provider to request an association. + /// Null if no association could be created that meet the security requirements + /// and the provider OpenID version. + /// </returns> + internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider, string associationType, string sessionType) { + Contract.Requires<ArgumentNullException>(securityRequirements != null); + Contract.Requires<ArgumentNullException>(provider != null); + Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType)); + Contract.Requires<ArgumentNullException>(sessionType != null); + + bool unencryptedAllowed = provider.Uri.IsTransportSecure(); + if (unencryptedAllowed) { + var associateRequest = new AssociateUnencryptedRequest(provider.Version, provider.Uri); + associateRequest.AssociationType = associationType; + return associateRequest; + } else { + var associateRequest = new AssociateDiffieHellmanRequest(provider.Version, provider.Uri); + associateRequest.AssociationType = associationType; + associateRequest.SessionType = sessionType; + associateRequest.InitializeRequest(); + return associateRequest; + } + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateSuccessfulResponseContract.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateSuccessfulResponseContract.cs new file mode 100644 index 0000000..de28a64 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateSuccessfulResponseContract.cs @@ -0,0 +1,17 @@ +namespace DotNetOpenAuth { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.OpenId.Messages; + using System.Diagnostics.Contracts; + using DotNetOpenAuth.OpenId; + + [ContractClassFor(typeof(AssociateSuccessfulResponseRelyingParty))] + internal abstract class AssociateSuccessfulResponseRelyingPartyContract : AssociateSuccessfulResponseRelyingParty { + protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { + Contract.Requires<ArgumentNullException>(request != null); + throw new NotImplementedException(); + } + } +} diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateSuccessfulResponseRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateSuccessfulResponseRelyingParty.cs new file mode 100644 index 0000000..7ee3988 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateSuccessfulResponseRelyingParty.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace DotNetOpenAuth.OpenId.Messages { + internal abstract class AssociateSuccessfulResponseRelyingParty : AssociateSuccessfulResponse { + /// <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.RelyingParty/OpenId/Messages/AssociateUnencryptedResponseRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateUnencryptedResponseRelyingParty.cs new file mode 100644 index 0000000..23cbd9b --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Messages/AssociateUnencryptedResponseRelyingParty.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace DotNetOpenAuth.OpenId.Messages { + internal class AssociateUnencryptedResponseRelyingParty : AssociateUnencryptedResponse { + + /// <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/Mvc/OpenIdAjaxOptions.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdAjaxOptions.cs index 4b88d04..4b88d04 100644 --- a/src/DotNetOpenAuth.OpenId/Mvc/OpenIdAjaxOptions.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdAjaxOptions.cs diff --git a/src/DotNetOpenAuth.OpenId/Mvc/OpenIdHelper.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdHelper.cs index b98e0d6..b98e0d6 100644 --- a/src/DotNetOpenAuth.OpenId/Mvc/OpenIdHelper.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdHelper.cs diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/OpenIdXrdsHelper.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/OpenIdXrdsHelper.cs new file mode 100644 index 0000000..6b2fb54 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/OpenIdXrdsHelper.cs @@ -0,0 +1,163 @@ +//----------------------------------------------------------------------- +// <copyright file="OpenIdXrdsHelper.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId { + using System; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.Linq; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.RelyingParty; + using DotNetOpenAuth.Xrds; + + /// <summary> + /// Adds OpenID-specific extension methods to the XrdsDocument class. + /// </summary> + internal static class OpenIdXrdsHelperRelyingParty { + /// <summary> + /// Creates the service endpoints described in this document, useful for requesting + /// authentication of one of the OpenID Providers that result from it. + /// </summary> + /// <param name="xrds">The XrdsDocument instance to use in this process.</param> + /// <param name="claimedIdentifier">The claimed identifier that was used to discover this XRDS document.</param> + /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> + /// <returns> + /// A sequence of OpenID Providers that can assert ownership of the <paramref name="claimedIdentifier"/>. + /// </returns> + internal static IEnumerable<IdentifierDiscoveryResult> CreateServiceEndpoints(this IEnumerable<XrdElement> xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) { + Contract.Requires<ArgumentNullException>(xrds != null); + Contract.Requires<ArgumentNullException>(claimedIdentifier != null); + Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null); + Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); + + var endpoints = new List<IdentifierDiscoveryResult>(); + endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier)); + endpoints.AddRange(xrds.GenerateClaimedIdentifierServiceEndpoints(claimedIdentifier, userSuppliedIdentifier)); + + Logger.Yadis.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count); + Logger.Yadis.Debug(endpoints.ToStringDeferred(true)); + return endpoints; + } + + /// <summary> + /// Creates the service endpoints described in this document, useful for requesting + /// authentication of one of the OpenID Providers that result from it. + /// </summary> + /// <param name="xrds">The XrdsDocument instance to use in this process.</param> + /// <param name="userSuppliedIdentifier">The user-supplied i-name that was used to discover this XRDS document.</param> + /// <returns>A sequence of OpenID Providers that can assert ownership of the canonical ID given in this document.</returns> + internal static IEnumerable<IdentifierDiscoveryResult> CreateServiceEndpoints(this IEnumerable<XrdElement> xrds, XriIdentifier userSuppliedIdentifier) { + Contract.Requires<ArgumentNullException>(xrds != null); + Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null); + Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); + + var endpoints = new List<IdentifierDiscoveryResult>(); + endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier)); + endpoints.AddRange(xrds.GenerateClaimedIdentifierServiceEndpoints(userSuppliedIdentifier)); + Logger.Yadis.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count); + Logger.Yadis.Debug(endpoints.ToStringDeferred(true)); + return endpoints; + } + + /// <summary> + /// Generates OpenID Providers that can authenticate using directed identity. + /// </summary> + /// <param name="xrds">The XrdsDocument instance to use in this process.</param> + /// <param name="opIdentifier">The OP Identifier entered (and resolved) by the user. Essentially the user-supplied identifier.</param> + /// <returns>A sequence of the providers that can offer directed identity services.</returns> + private static IEnumerable<IdentifierDiscoveryResult> GenerateOPIdentifierServiceEndpoints(this IEnumerable<XrdElement> xrds, Identifier opIdentifier) { + Contract.Requires<ArgumentNullException>(xrds != null); + Contract.Requires<ArgumentNullException>(opIdentifier != null); + Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); + return from service in xrds.FindOPIdentifierServices() + from uri in service.UriElements + let protocol = Protocol.FindBestVersion(p => p.OPIdentifierServiceTypeURI, service.TypeElementUris) + let providerDescription = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris) + select IdentifierDiscoveryResult.CreateForProviderIdentifier(opIdentifier, providerDescription, service.Priority, uri.Priority); + } + + /// <summary> + /// Generates the OpenID Providers that are capable of asserting ownership + /// of a particular URI claimed identifier. + /// </summary> + /// <param name="xrds">The XrdsDocument instance to use in this process.</param> + /// <param name="claimedIdentifier">The claimed identifier.</param> + /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> + /// <returns> + /// A sequence of the providers that can assert ownership of the given identifier. + /// </returns> + private static IEnumerable<IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this IEnumerable<XrdElement> xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) { + Contract.Requires<ArgumentNullException>(xrds != null); + Contract.Requires<ArgumentNullException>(claimedIdentifier != null); + Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); + + return from service in xrds.FindClaimedIdentifierServices() + from uri in service.UriElements + where uri.Uri != null + let providerEndpoint = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris) + select IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, providerEndpoint, service.Priority, uri.Priority); + } + + /// <summary> + /// Generates the OpenID Providers that are capable of asserting ownership + /// of a particular XRI claimed identifier. + /// </summary> + /// <param name="xrds">The XrdsDocument instance to use in this process.</param> + /// <param name="userSuppliedIdentifier">The i-name supplied by the user.</param> + /// <returns>A sequence of the providers that can assert ownership of the given identifier.</returns> + private static IEnumerable<IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this IEnumerable<XrdElement> xrds, XriIdentifier userSuppliedIdentifier) { + // Cannot use code contracts because this method uses yield return. + ////Contract.Requires<ArgumentNullException>(xrds != null); + ////Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); + ErrorUtilities.VerifyArgumentNotNull(xrds, "xrds"); + + foreach (var service in xrds.FindClaimedIdentifierServices()) { + foreach (var uri in service.UriElements) { + // spec section 7.3.2.3 on Claimed Id -> CanonicalID substitution + if (service.Xrd.CanonicalID == null) { + Logger.Yadis.WarnFormat(XrdsStrings.MissingCanonicalIDElement, userSuppliedIdentifier); + break; // skip on to next service + } + ErrorUtilities.VerifyProtocol(service.Xrd.IsCanonicalIdVerified, XrdsStrings.CIDVerificationFailed, userSuppliedIdentifier); + + // In the case of XRI names, the ClaimedId is actually the CanonicalID. + var claimedIdentifier = new XriIdentifier(service.Xrd.CanonicalID); + var providerEndpoint = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris); + yield return IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, providerEndpoint, service.Priority, uri.Priority); + } + } + } + + /// <summary> + /// Enumerates the XRDS service elements that describe OpenID Providers offering directed identity assertions. + /// </summary> + /// <param name="xrds">The XrdsDocument instance to use in this process.</param> + /// <returns>A sequence of service elements.</returns> + private static IEnumerable<ServiceElement> FindOPIdentifierServices(this IEnumerable<XrdElement> xrds) { + Contract.Requires<ArgumentNullException>(xrds != null); + Contract.Ensures(Contract.Result<IEnumerable<ServiceElement>>() != null); + + return from xrd in xrds + from service in xrd.OpenIdProviderIdentifierServices + select service; + } + + /// <summary> + /// Returns the OpenID-compatible services described by a given XRDS document, + /// in priority order. + /// </summary> + /// <param name="xrds">The XrdsDocument instance to use in this process.</param> + /// <returns>A sequence of the services offered.</returns> + private static IEnumerable<ServiceElement> FindClaimedIdentifierServices(this IEnumerable<XrdElement> xrds) { + Contract.Requires<ArgumentNullException>(xrds != null); + Contract.Ensures(Contract.Result<IEnumerable<ServiceElement>>() != null); + + return from xrd in xrds + from service in xrd.OpenIdClaimedIdentifierServices + select service; + } + } +} diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ProviderEndpointDescription.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ProviderEndpointDescription.cs index 6514ffd..6514ffd 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ProviderEndpointDescription.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ProviderEndpointDescription.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AssociationManager.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AssociationManager.cs index 9a43506..9a43506 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AssociationManager.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AssociationManager.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AssociationPreference.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AssociationPreference.cs index 9f4a21f..9f4a21f 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AssociationPreference.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AssociationPreference.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/Associations.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/Associations.cs index b171bec..b171bec 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/Associations.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/Associations.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AuthenticationRequest.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AuthenticationRequest.cs index d79038c..d79038c 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AuthenticationRequest.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AuthenticationRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AuthenticationStatus.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AuthenticationStatus.cs index d9e5d0a..d9e5d0a 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AuthenticationStatus.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AuthenticationStatus.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/Controls.cd b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/Controls.cd index f96db36..f96db36 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/Controls.cd +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/Controls.cd diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/CryptoKeyStoreAsRelyingPartyAssociationStore.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/CryptoKeyStoreAsRelyingPartyAssociationStore.cs index 02ed3b0..02ed3b0 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/CryptoKeyStoreAsRelyingPartyAssociationStore.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/CryptoKeyStoreAsRelyingPartyAssociationStore.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/DuplicateRequestedHostsComparer.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/DuplicateRequestedHostsComparer.cs index 94eb5ba..94eb5ba 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/DuplicateRequestedHostsComparer.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/DuplicateRequestedHostsComparer.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/FailedAuthenticationResponse.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/FailedAuthenticationResponse.cs index 682e3ff..682e3ff 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/FailedAuthenticationResponse.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/FailedAuthenticationResponse.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IAuthenticationRequest.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IAuthenticationRequest.cs index 65db0bd..65db0bd 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IAuthenticationRequest.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IAuthenticationRequest.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IAuthenticationRequestContract.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IAuthenticationRequestContract.cs index cd36cc7..cd36cc7 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IAuthenticationRequestContract.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IAuthenticationRequestContract.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IAuthenticationResponse.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IAuthenticationResponse.cs index a24220f..a24220f 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IAuthenticationResponse.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IAuthenticationResponse.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IProviderEndpoint.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IProviderEndpoint.cs index 5d8918d..5d8918d 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IProviderEndpoint.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IProviderEndpoint.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IRelyingPartyAssociationStore.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IRelyingPartyAssociationStore.cs index 21a2c53..21a2c53 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IRelyingPartyAssociationStore.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IRelyingPartyAssociationStore.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IRelyingPartyBehavior.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IRelyingPartyBehavior.cs index 1bfa0db..1bfa0db 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/IRelyingPartyBehavior.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/IRelyingPartyBehavior.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/ISetupRequiredAuthenticationResponse.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/ISetupRequiredAuthenticationResponse.cs index cfbccef..cfbccef 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/ISetupRequiredAuthenticationResponse.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/ISetupRequiredAuthenticationResponse.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/NegativeAuthenticationResponse.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/NegativeAuthenticationResponse.cs index 9e3824d..9e3824d 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/NegativeAuthenticationResponse.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/NegativeAuthenticationResponse.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs index 42bfbde..42bfbde 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdAjaxTextBox.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.cs index 8be097f..8be097f 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdAjaxTextBox.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdAjaxTextBox.css b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.css index bed2e79..bed2e79 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdAjaxTextBox.css +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.css diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdAjaxTextBox.js b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.js index 9907b4e..9907b4e 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdAjaxTextBox.js +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.js diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdButton.cs index 6243917..6243917 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdButton.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdButton.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdEventArgs.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdEventArgs.cs index 5668cf4..5668cf4 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdEventArgs.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdEventArgs.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdLogin.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdLogin.cs index eccdacf..eccdacf 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdLogin.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdLogin.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdMobileTextBox.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdMobileTextBox.cs index fc80b32..fc80b32 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdMobileTextBox.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdMobileTextBox.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingParty.cd b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cd index 0519ecb..0519ecb 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingParty.cd +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cd diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs index 290d29e..290d29e 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingParty.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs index eaaba8c..eaaba8c 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js index 4de5188..4de5188 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs index 16ea839..16ea839 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js index 58b283d..58b283d 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdSelector.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.cs index ae1037b..ae1037b 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdSelector.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdSelector.css b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.css index e7eafc7..e7eafc7 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdSelector.css +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.css diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdSelector.js b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.js index 297ea23..297ea23 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdSelector.js +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.js diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdTextBox.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdTextBox.cs index 335b435..335b435 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/OpenIdTextBox.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdTextBox.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/PopupBehavior.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PopupBehavior.cs index e84f4f5..e84f4f5 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/PopupBehavior.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PopupBehavior.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/PositiveAnonymousResponse.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PositiveAnonymousResponse.cs index fc334b0..fc334b0 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/PositiveAnonymousResponse.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PositiveAnonymousResponse.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/PositiveAuthenticationResponse.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PositiveAuthenticationResponse.cs index 3e2298c..3e2298c 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/PositiveAuthenticationResponse.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PositiveAuthenticationResponse.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshot.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshot.cs index 80b424a..80b424a 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshot.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshot.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/RelyingPartySecuritySettings.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/RelyingPartySecuritySettings.cs index fc6d4c7..fc6d4c7 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/RelyingPartySecuritySettings.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/RelyingPartySecuritySettings.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButton.cs index 0be3a5f..0be3a5f 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorButton.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButton.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorButtonContract.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButtonContract.cs index c70218a..c70218a 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorButtonContract.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButtonContract.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorInfoCardButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorInfoCardButton.cs index c5dda1c..c5dda1c 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorInfoCardButton.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorInfoCardButton.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorOpenIdButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorOpenIdButton.cs index ac4dcbf..ac4dcbf 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorOpenIdButton.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorOpenIdButton.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorProviderButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorProviderButton.cs index 2195e73..2195e73 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SelectorProviderButton.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorProviderButton.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SimpleXrdsProviderEndpoint.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SimpleXrdsProviderEndpoint.cs index 678f69a..678f69a 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/SimpleXrdsProviderEndpoint.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SimpleXrdsProviderEndpoint.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/StandardRelyingPartyApplicationStore.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/StandardRelyingPartyApplicationStore.cs index a14b55d..a14b55d 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/StandardRelyingPartyApplicationStore.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/StandardRelyingPartyApplicationStore.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/WellKnownProviders.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/WellKnownProviders.cs index ad1a11a..ad1a11a 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/WellKnownProviders.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/WellKnownProviders.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/login_failure.png b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_failure.png Binary files differindex 8003700..8003700 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/login_failure.png +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_failure.png diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/login_success (lock).png b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success (lock).png Binary files differindex bc0c0c8..bc0c0c8 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/login_success (lock).png +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success (lock).png diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/login_success.png b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success.png Binary files differindex 0ae1365..0ae1365 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/login_success.png +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success.png diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/openid_login.png b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/openid_login.png Binary files differindex caebd58..caebd58 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/openid_login.png +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/openid_login.png diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/spinner.gif b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/spinner.gif Binary files differindex 9cb298e..9cb298e 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/spinner.gif +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/spinner.gif diff --git a/src/DotNetOpenAuth.OpenId/OpenId/UriDiscoveryService.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/UriDiscoveryService.cs index 7d17fd9..7d17fd9 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/UriDiscoveryService.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/UriDiscoveryService.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/XriDiscoveryProxyService.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/XriDiscoveryProxyService.cs index d80c59e..d80c59e 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/XriDiscoveryProxyService.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/XriDiscoveryProxyService.cs diff --git a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdElement.cs b/src/DotNetOpenAuth.OpenId/Configuration/OpenIdElement.cs index 4742172..e45e56e 100644 --- a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdElement.cs +++ b/src/DotNetOpenAuth.OpenId/Configuration/OpenIdElement.cs @@ -10,28 +10,19 @@ namespace DotNetOpenAuth.Configuration { using System.Diagnostics.Contracts; using DotNetOpenAuth.OpenId.ChannelElements; using DotNetOpenAuth.OpenId.Messages; + using System.Collections.Generic; /// <summary> /// Represents the <openid> element in the host's .config file. /// </summary> [ContractVerification(true)] - internal class OpenIdElement : ConfigurationSection { + internal class OpenIdElement : ConfigurationSectionGroup { /// <summary> /// The name of the section under which this library's settings must be found. /// </summary> private const string SectionName = DotNetOpenAuthSection.SectionName + "/openid"; /// <summary> - /// The name of the <relyingParty> sub-element. - /// </summary> - private const string RelyingPartyElementName = "relyingParty"; - - /// <summary> - /// The name of the <provider> sub-element. - /// </summary> - private const string ProviderElementName = "provider"; - - /// <summary> /// The name of the <extensions> sub-element. /// </summary> private const string ExtensionFactoriesElementName = "extensionFactories"; @@ -57,6 +48,8 @@ namespace DotNetOpenAuth.Configuration { internal OpenIdElement() { } + private Dictionary<string, object> indexer; + /// <summary> /// Gets the configuration section from the .config file. /// </summary> @@ -80,14 +73,14 @@ namespace DotNetOpenAuth.Configuration { internal TimeSpan MaxAuthenticationTime { get { Contract.Ensures(Contract.Result<TimeSpan>() > TimeSpan.Zero); - TimeSpan result = (TimeSpan)this[MaxAuthenticationTimePropertyName]; + TimeSpan result = (TimeSpan)indexer[MaxAuthenticationTimePropertyName]; Contract.Assume(result > TimeSpan.Zero); // our PositiveTimeSpanValidator should take care of this return result; } set { Contract.Requires<ArgumentOutOfRangeException>(value > TimeSpan.Zero); - this[MaxAuthenticationTimePropertyName] = value; + indexer[MaxAuthenticationTimePropertyName] = value; } } @@ -105,26 +98,8 @@ namespace DotNetOpenAuth.Configuration { /// </remarks> [ConfigurationProperty(CacheDiscoveryPropertyName, DefaultValue = true)] internal bool CacheDiscovery { - get { return (bool)this[CacheDiscoveryPropertyName]; } - set { this[CacheDiscoveryPropertyName] = value; } - } - - /// <summary> - /// Gets or sets the configuration specific for Relying Parties. - /// </summary> - [ConfigurationProperty(RelyingPartyElementName)] - internal OpenIdRelyingPartyElement RelyingParty { - get { return (OpenIdRelyingPartyElement)this[RelyingPartyElementName] ?? new OpenIdRelyingPartyElement(); } - set { this[RelyingPartyElementName] = value; } - } - - /// <summary> - /// Gets or sets the configuration specific for Providers. - /// </summary> - [ConfigurationProperty(ProviderElementName)] - internal OpenIdProviderElement Provider { - get { return (OpenIdProviderElement)this[ProviderElementName] ?? new OpenIdProviderElement(); } - set { this[ProviderElementName] = value; } + get { return (bool)indexer[CacheDiscoveryPropertyName]; } + set { indexer[CacheDiscoveryPropertyName] = value; } } /// <summary> @@ -133,8 +108,8 @@ namespace DotNetOpenAuth.Configuration { [ConfigurationProperty(ExtensionFactoriesElementName, IsDefaultCollection = false)] [ConfigurationCollection(typeof(TypeConfigurationCollection<IOpenIdExtensionFactory>))] internal TypeConfigurationCollection<IOpenIdExtensionFactory> ExtensionFactories { - get { return (TypeConfigurationCollection<IOpenIdExtensionFactory>)this[ExtensionFactoriesElementName] ?? new TypeConfigurationCollection<IOpenIdExtensionFactory>(); } - set { this[ExtensionFactoriesElementName] = value; } + get { return (TypeConfigurationCollection<IOpenIdExtensionFactory>)indexer[ExtensionFactoriesElementName] ?? new TypeConfigurationCollection<IOpenIdExtensionFactory>(); } + set { indexer[ExtensionFactoriesElementName] = value; } } /// <summary> @@ -142,8 +117,8 @@ namespace DotNetOpenAuth.Configuration { /// </summary> [ConfigurationProperty(XriResolverElementName)] internal XriResolverElement XriResolver { - get { return (XriResolverElement)this[XriResolverElementName] ?? new XriResolverElement(); } - set { this[XriResolverElementName] = value; } + get { return (XriResolverElement)indexer[XriResolverElementName] ?? new XriResolverElement(); } + set { indexer[XriResolverElementName] = value; } } } } diff --git a/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj b/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj index 4d7d1ce..eeffeee 100644 --- a/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj +++ b/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj @@ -20,41 +20,24 @@ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> </PropertyGroup> <ItemGroup> - <Compile Include="ComponentModel\IdentifierConverter.cs" /> <Compile Include="Configuration\AssociationTypeCollection.cs" /> <Compile Include="Configuration\AssociationTypeElement.cs" /> <Compile Include="Configuration\OpenIdElement.cs" /> - <Compile Include="Configuration\OpenIdProviderElement.cs" /> - <Compile Include="Configuration\OpenIdProviderSecuritySettingsElement.cs" /> - <Compile Include="Configuration\OpenIdRelyingPartyElement.cs" /> - <Compile Include="Configuration\OpenIdRelyingPartySecuritySettingsElement.cs" /> <Compile Include="Configuration\XriResolverElement.cs" /> - <Compile Include="Mvc\OpenIdAjaxOptions.cs" /> - <Compile Include="Mvc\OpenIdHelper.cs" /> <Compile Include="OpenId\Association.cs" /> - <Compile Include="OpenId\Provider\AssociationDataBag.cs" /> - <Compile Include="OpenId\Provider\IdentityEndpoint.cs" /> - <Compile Include="OpenId\Provider\IdentityEndpointNormalizationEventArgs.cs" /> - <Compile Include="OpenId\Provider\IProviderAssociationStore.cs" /> - <Compile Include="OpenId\Provider\ProviderAssociationHandleEncoder.cs" /> - <Compile Include="OpenId\Provider\ProviderAssociationKeyStorage.cs" /> - <Compile Include="OpenId\RelyingParty\CryptoKeyStoreAsRelyingPartyAssociationStore.cs" /> - <Compile Include="OpenId\RelyingParty\IRelyingPartyAssociationStore.cs" /> - <Compile Include="OpenId\RelyingParty\Associations.cs" /> + <Compile Include="OpenId\AuthenticationRequestMode.cs" /> <Compile Include="OpenId\Behaviors\AXFetchAsSregTransform.cs" /> <Compile Include="OpenId\Behaviors\BehaviorStrings.Designer.cs"> <AutoGen>True</AutoGen> <DesignTime>True</DesignTime> <DependentUpon>BehaviorStrings.resx</DependentUpon> </Compile> - <Compile Include="OpenId\Behaviors\PpidGeneration.cs" /> + <Compile Include="OpenId\Behaviors\GsaIcamProfile.cs" /> <Compile Include="OpenId\ChannelElements\BackwardCompatibilityBindingElement.cs" /> <Compile Include="OpenId\ChannelElements\ExtensionsBindingElement.cs" /> <Compile Include="OpenId\ChannelElements\IOpenIdExtensionFactory.cs" /> <Compile Include="OpenId\ChannelElements\ITamperResistantOpenIdMessage.cs" /> <Compile Include="OpenId\ChannelElements\OriginalStringUriEncoder.cs" /> - <Compile Include="OpenId\ChannelElements\RelyingPartySecurityOptions.cs" /> - <Compile Include="OpenId\ChannelElements\ReturnToNonceBindingElement.cs" /> <Compile Include="OpenId\ChannelElements\SigningBindingElement.cs" /> <Compile Include="OpenId\ChannelElements\KeyValueFormEncoding.cs" /> <Compile Include="OpenId\ChannelElements\OpenIdChannel.cs" /> @@ -95,17 +78,11 @@ <Compile Include="OpenId\Extensions\SimpleRegistration\DemandLevel.cs" /> <Compile Include="OpenId\Extensions\SimpleRegistration\Gender.cs" /> <Compile Include="OpenId\Extensions\UI\UIConstants.cs" /> - <Compile Include="OpenId\Extensions\UI\UIUtilities.cs" /> <Compile Include="OpenId\Extensions\UI\UIModes.cs" /> <Compile Include="OpenId\Extensions\UI\UIRequest.cs" /> - <Compile Include="OpenId\HostMetaDiscoveryService.cs" /> <Compile Include="OpenId\Identifier.cs" /> <Compile Include="OpenId\IdentifierContract.cs" /> <Compile Include="OpenId\Extensions\ExtensionsInteropHelper.cs" /> - <Compile Include="OpenId\Interop\AuthenticationResponseShim.cs" /> - <Compile Include="OpenId\Interop\ClaimsResponseShim.cs" /> - <Compile Include="OpenId\Interop\OpenIdRelyingPartyShim.cs" /> - <Compile Include="OpenId\IIdentifierDiscoveryService.cs" /> <Compile Include="OpenId\Messages\CheckAuthenticationRequest.cs" /> <Compile Include="OpenId\Messages\CheckAuthenticationResponse.cs" /> <Compile Include="OpenId\Messages\CheckIdRequest.cs" /> @@ -119,42 +96,12 @@ <Compile Include="OpenId\Messages\SignedResponseRequest.cs" /> <Compile Include="OpenId\NoDiscoveryIdentifier.cs" /> <Compile Include="OpenId\OpenIdUtilities.cs" /> - <Compile Include="OpenId\Provider\AssociationRelyingPartyType.cs" /> - <Compile Include="OpenId\Provider\PrivatePersonalIdentifierProviderBase.cs" /> - <Compile Include="OpenId\Provider\AnonymousRequest.cs" /> - <Compile Include="OpenId\Provider\AnonymousRequestEventArgs.cs" /> - <Compile Include="OpenId\Provider\AuthenticationChallengeEventArgs.cs" /> - <Compile Include="OpenId\Provider\AuthenticationRequest.cs" /> - <Compile Include="OpenId\Provider\AutoResponsiveRequest.cs" /> - <Compile Include="OpenId\Provider\HostProcessedRequest.cs" /> - <Compile Include="OpenId\Provider\IAnonymousRequest.cs" /> - <Compile Include="OpenId\Provider\IAuthenticationRequest.cs" /> - <Compile Include="OpenId\Provider\IDirectedIdentityIdentifierProvider.cs" /> - <Compile Include="OpenId\Provider\IHostProcessedRequest.cs" /> - <Compile Include="OpenId\Provider\IErrorReporting.cs" /> - <Compile Include="OpenId\Provider\IProviderBehavior.cs" /> - <Compile Include="OpenId\Provider\IRequest.cs" /> - <Compile Include="OpenId\Provider\ProviderEndpoint.cs" /> - <Compile Include="OpenId\Provider\RelyingPartyDiscoveryResult.cs" /> - <Compile Include="OpenId\Provider\Request.cs" /> - <Compile Include="OpenId\Provider\RequestContract.cs" /> - <Compile Include="OpenId\Provider\StandardProviderApplicationStore.cs" /> + <Compile Include="OpenId\OpenIdXrdsHelper.cs" /> <Compile Include="OpenId\Realm.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\Messages\AssociateUnencryptedRequest.cs" /> - <Compile Include="OpenId\Provider\OpenIdProvider.cs" /> <Compile Include="OpenId\Messages\AssociateDiffieHellmanRequest.cs" /> <Compile Include="OpenId\Messages\AssociateDiffieHellmanResponse.cs" /> <Compile Include="OpenId\Messages\AssociateRequest.cs" /> @@ -165,59 +112,15 @@ <Compile Include="OpenId\Messages\DirectErrorResponse.cs" /> <Compile Include="OpenId\Messages\RequestBase.cs" /> <Compile Include="OpenId\Messages\DirectResponseBase.cs" /> - <Compile Include="OpenId\RelyingParty\AssociationManager.cs" /> - <Compile Include="OpenId\RelyingParty\AssociationPreference.cs" /> - <Compile Include="OpenId\RelyingParty\AuthenticationRequest.cs" /> - <Compile Include="OpenId\RelyingParty\AuthenticationRequestMode.cs" /> - <Compile Include="OpenId\RelyingParty\DuplicateRequestedHostsComparer.cs" /> - <Compile Include="OpenId\RelyingParty\IProviderEndpoint.cs" /> - <Compile Include="OpenId\RelyingParty\IRelyingPartyBehavior.cs" /> - <Compile Include="OpenId\RelyingParty\IAuthenticationRequestContract.cs" /> - <Compile Include="OpenId\RelyingParty\NegativeAuthenticationResponse.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdAjaxRelyingParty.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdAjaxTextBox.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdButton.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdEventArgs.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdLogin.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdMobileTextBox.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdSelector.cs" /> - <Compile Include="OpenId\RelyingParty\OpenIdTextBox.cs" /> - <Compile Include="OpenId\RelyingParty\PopupBehavior.cs" /> - <Compile Include="OpenId\RelyingParty\PositiveAnonymousResponse.cs" /> - <Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponse.cs" /> - <Compile Include="OpenId\RelyingParty\AuthenticationStatus.cs" /> - <Compile Include="OpenId\RelyingParty\FailedAuthenticationResponse.cs" /> - <Compile Include="OpenId\RelyingParty\IAuthenticationRequest.cs" /> - <Compile Include="OpenId\RelyingParty\IAuthenticationResponse.cs" /> - <Compile Include="OpenId\RelyingParty\ISetupRequiredAuthenticationResponse.cs" /> - <Compile Include="OpenId\RelyingParty\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\ProviderEndpointDescription.cs" /> - <Compile Include="OpenId\Provider\ProviderSecuritySettings.cs" /> <Compile Include="OpenId\IOpenIdApplicationStore.cs" /> - <Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponseSnapshot.cs" /> - <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettings.cs" /> - <Compile Include="OpenId\IdentifierDiscoveryResult.cs" /> - <Compile Include="OpenId\OpenIdXrdsHelper.cs" /> - <Compile Include="OpenId\RelyingParty\SelectorButton.cs" /> - <Compile Include="OpenId\RelyingParty\SelectorButtonContract.cs" /> - <Compile Include="OpenId\RelyingParty\SelectorOpenIdButton.cs" /> - <Compile Include="OpenId\RelyingParty\SelectorProviderButton.cs" /> - <Compile Include="OpenId\RelyingParty\SimpleXrdsProviderEndpoint.cs" /> - <Compile Include="OpenId\RelyingParty\StandardRelyingPartyApplicationStore.cs" /> - <Compile Include="OpenId\Behaviors\GsaIcamProfile.cs" /> - <Compile Include="OpenId\RelyingParty\WellKnownProviders.cs" /> <Compile Include="OpenId\SecuritySettings.cs" /> - <Compile Include="OpenId\UriDiscoveryService.cs" /> <Compile Include="OpenId\UriIdentifier.cs" /> - <Compile Include="OpenId\XriDiscoveryProxyService.cs" /> <Compile Include="OpenId\XriIdentifier.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="XrdsPublisher.cs" /> @@ -247,27 +150,14 @@ <EmbeddedResource Include="Xrds\XrdsStrings.sr.resx" /> </ItemGroup> <ItemGroup> - <Content Include="OpenId\RelyingParty\login_failure.png" /> - <Content Include="OpenId\RelyingParty\login_success %28lock%29.png" /> - <Content Include="OpenId\RelyingParty\login_success.png" /> - <Content Include="OpenId\RelyingParty\OpenIdAjaxTextBox.css" /> - <Content Include="OpenId\RelyingParty\OpenIdAjaxTextBox.js" /> - <Content Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.js" /> - <Content Include="OpenId\RelyingParty\OpenIdRelyingPartyControlBase.js" /> - <Content Include="OpenId\RelyingParty\OpenIdSelector.css" /> - <Content Include="OpenId\RelyingParty\OpenIdSelector.js" /> - <Content Include="OpenId\RelyingParty\openid_login.png" /> - <Content Include="OpenId\RelyingParty\spinner.gif" /> - </ItemGroup> - <ItemGroup> - <None Include="OpenId\RelyingParty\Controls.cd" /> - <None Include="OpenId\RelyingParty\OpenIdRelyingParty.cd" /> - </ItemGroup> - <ItemGroup> <ProjectReference Include="..\DotNetOpenAuth.Messaging\DotNetOpenAuth.Messaging.csproj"> <Project>{60426312-6AE5-4835-8667-37EDEA670222}</Project> <Name>DotNetOpenAuth.Messaging</Name> </ProjectReference> + <ProjectReference Include="..\Org.Mentalis.Security.Cryptography\Org.Mentalis.Security.Cryptography.csproj"> + <Project>{26DC877F-5987-48DD-9DDB-E62F2DE0E150}</Project> + <Name>Org.Mentalis.Security.Cryptography</Name> + </ProjectReference> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" /> diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Association.cs b/src/DotNetOpenAuth.OpenId/OpenId/Association.cs index 06f920a..0143838 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Association.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Association.cs @@ -14,7 +14,6 @@ namespace DotNetOpenAuth.OpenId { using System.Text; using DotNetOpenAuth.Configuration; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// Stores a secret used in signing and verifying messages. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AuthenticationRequestMode.cs b/src/DotNetOpenAuth.OpenId/OpenId/AuthenticationRequestMode.cs index 70b7f3a..dfe7b06 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/RelyingParty/AuthenticationRequestMode.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/AuthenticationRequestMode.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.OpenId.RelyingParty { +namespace DotNetOpenAuth.OpenId { /// <summary> /// Indicates the mode the Provider should use while authenticating the end user. /// </summary> diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/AXFetchAsSregTransform.cs b/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/AXFetchAsSregTransform.cs index 01b74a1..510435c 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/AXFetchAsSregTransform.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/AXFetchAsSregTransform.cs @@ -14,8 +14,6 @@ namespace DotNetOpenAuth.OpenId.Behaviors { using DotNetOpenAuth.OpenId.Extensions; using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// An Attribute Exchange and Simple Registration filter to make all incoming attribute @@ -23,7 +21,7 @@ namespace DotNetOpenAuth.OpenId.Behaviors { /// to the originally requested extension and format. /// </summary> [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Abbreviation")] - public sealed class AXFetchAsSregTransform : IRelyingPartyBehavior, IProviderBehavior { + public class AXFetchAsSregTransform { /// <summary> /// Initializes static members of the <see cref="AXFetchAsSregTransform"/> class. /// </summary> @@ -41,99 +39,5 @@ namespace DotNetOpenAuth.OpenId.Behaviors { /// Gets or sets the AX attribute type URI formats this transform is willing to work with. /// </summary> public static AXAttributeFormats AXFormats { get; set; } - - #region IRelyingPartyBehavior Members - - /// <summary> - /// Applies a well known set of security requirements to a default set of security settings. - /// </summary> - /// <param name="securitySettings">The security settings to enhance with the requirements of this profile.</param> - /// <remarks> - /// Care should be taken to never decrease security when applying a profile. - /// Profiles should only enhance security requirements to avoid being - /// incompatible with each other. - /// </remarks> - void IRelyingPartyBehavior.ApplySecuritySettings(RelyingPartySecuritySettings securitySettings) { - } - - /// <summary> - /// Called when an authentication request is about to be sent. - /// </summary> - /// <param name="request">The request.</param> - /// <remarks> - /// Implementations should be prepared to be called multiple times on the same outgoing message - /// without malfunctioning. - /// </remarks> - void IRelyingPartyBehavior.OnOutgoingAuthenticationRequest(RelyingParty.IAuthenticationRequest request) { - // Don't create AX extensions for OpenID 1.x messages, since AX requires OpenID 2.0. - if (request.Provider.Version.Major >= 2) { - request.SpreadSregToAX(AXFormats); - } - } - - /// <summary> - /// Called when an incoming positive assertion is received. - /// </summary> - /// <param name="assertion">The positive assertion.</param> - void IRelyingPartyBehavior.OnIncomingPositiveAssertion(IAuthenticationResponse assertion) { - if (assertion.GetExtension<ClaimsResponse>() == null) { - ClaimsResponse sreg = assertion.UnifyExtensionsAsSreg(true); - ((PositiveAnonymousResponse)assertion).Response.Extensions.Add(sreg); - } - } - - #endregion - - #region IProviderBehavior Members - - /// <summary> - /// Applies a well known set of security requirements to a default set of security settings. - /// </summary> - /// <param name="securitySettings">The security settings to enhance with the requirements of this profile.</param> - /// <remarks> - /// Care should be taken to never decrease security when applying a profile. - /// Profiles should only enhance security requirements to avoid being - /// incompatible with each other. - /// </remarks> - void IProviderBehavior.ApplySecuritySettings(ProviderSecuritySettings securitySettings) { - // Nothing to do here. - } - - /// <summary> - /// Called when a request is received by the Provider. - /// </summary> - /// <param name="request">The incoming request.</param> - /// <returns> - /// <c>true</c> if this behavior owns this request and wants to stop other behaviors - /// from handling it; <c>false</c> to allow other behaviors to process this request. - /// </returns> - /// <remarks> - /// Implementations may set a new value to <see cref="IRequest.SecuritySettings"/> but - /// should not change the properties on the instance of <see cref="ProviderSecuritySettings"/> - /// itself as that instance may be shared across many requests. - /// </remarks> - bool IProviderBehavior.OnIncomingRequest(IRequest request) { - var extensionRequest = request as Provider.HostProcessedRequest; - if (extensionRequest != null) { - extensionRequest.UnifyExtensionsAsSreg(); - } - - return false; - } - - /// <summary> - /// Called when the Provider is preparing to send a response to an authentication request. - /// </summary> - /// <param name="request">The request that is configured to generate the outgoing response.</param> - /// <returns> - /// <c>true</c> if this behavior owns this request and wants to stop other behaviors - /// from handling it; <c>false</c> to allow other behaviors to process this request. - /// </returns> - bool IProviderBehavior.OnOutgoingResponse(Provider.IAuthenticationRequest request) { - request.ConvertSregToMatchRequest(); - return false; - } - - #endregion } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/GsaIcamProfile.cs b/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/GsaIcamProfile.cs index 317a2b4..c84e570 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/GsaIcamProfile.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Behaviors/GsaIcamProfile.cs @@ -14,8 +14,6 @@ namespace DotNetOpenAuth.OpenId.Behaviors { using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy; using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// Implements the Identity, Credential, & Access Management (ICAM) OpenID 2.0 Profile @@ -28,12 +26,7 @@ namespace DotNetOpenAuth.OpenId.Behaviors { /// </remarks> [Serializable] [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Icam", Justification = "Acronym")] - public sealed class GsaIcamProfile : IRelyingPartyBehavior, IProviderBehavior { - /// <summary> - /// The maximum time a shared association can live. - /// </summary> - private static readonly TimeSpan MaximumAssociationLifetime = TimeSpan.FromSeconds(86400); - + public abstract class GsaIcamProfile { /// <summary> /// Backing field for the <see cref="DisableSslRequirement"/> static property. /// </summary> @@ -49,12 +42,6 @@ namespace DotNetOpenAuth.OpenId.Behaviors { } /// <summary> - /// Gets or sets the provider for generating PPID identifiers. - /// </summary> - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ppid", Justification = "Acronym")] - public static IDirectedIdentityIdentifierProvider PpidIdentifierProvider { get; set; } - - /// <summary> /// Gets or sets a value indicating whether PII is allowed to be requested or received via OpenID. /// </summary> /// <value>The default value is <c>false</c>.</value> @@ -67,228 +54,5 @@ namespace DotNetOpenAuth.OpenId.Behaviors { get { return disableSslRequirement; } set { disableSslRequirement = value; } } - - #region IRelyingPartyBehavior Members - - /// <summary> - /// Applies a well known set of security requirements. - /// </summary> - /// <param name="securitySettings">The security settings to enhance with the requirements of this profile.</param> - /// <remarks> - /// Care should be taken to never decrease security when applying a profile. - /// Profiles should only enhance security requirements to avoid being - /// incompatible with each other. - /// </remarks> - void IRelyingPartyBehavior.ApplySecuritySettings(RelyingPartySecuritySettings securitySettings) { - if (securitySettings.MaximumHashBitLength < 256) { - securitySettings.MaximumHashBitLength = 256; - } - - securitySettings.RequireSsl = !DisableSslRequirement; - securitySettings.RequireDirectedIdentity = true; - securitySettings.RequireAssociation = true; - securitySettings.RejectDelegatingIdentifiers = true; - securitySettings.IgnoreUnsignedExtensions = true; - securitySettings.MinimumRequiredOpenIdVersion = ProtocolVersion.V20; - } - - /// <summary> - /// Called when an authentication request is about to be sent. - /// </summary> - /// <param name="request">The request.</param> - void IRelyingPartyBehavior.OnOutgoingAuthenticationRequest(RelyingParty.IAuthenticationRequest request) { - RelyingParty.AuthenticationRequest requestInternal = (RelyingParty.AuthenticationRequest)request; - ErrorUtilities.VerifyProtocol(string.Equals(request.Realm.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal) || DisableSslRequirement, BehaviorStrings.RealmMustBeHttps); - - var pape = requestInternal.AppliedExtensions.OfType<PolicyRequest>().SingleOrDefault(); - if (pape == null) { - request.AddExtension(pape = new PolicyRequest()); - } - - if (!pape.PreferredPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { - pape.PreferredPolicies.Add(AuthenticationPolicies.PrivatePersonalIdentifier); - } - - if (!pape.PreferredPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1)) { - pape.PreferredPolicies.Add(AuthenticationPolicies.USGovernmentTrustLevel1); - } - - if (!AllowPersonallyIdentifiableInformation && !pape.PreferredPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { - pape.PreferredPolicies.Add(AuthenticationPolicies.NoPersonallyIdentifiableInformation); - } - - if (pape.PreferredPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { - ErrorUtilities.VerifyProtocol( - (!requestInternal.AppliedExtensions.OfType<ClaimsRequest>().Any() && - !requestInternal.AppliedExtensions.OfType<FetchRequest>().Any()), - BehaviorStrings.PiiIncludedWithNoPiiPolicy); - } - - Reporting.RecordEventOccurrence(this, "RP"); - } - - /// <summary> - /// Called when an incoming positive assertion is received. - /// </summary> - /// <param name="assertion">The positive assertion.</param> - void IRelyingPartyBehavior.OnIncomingPositiveAssertion(IAuthenticationResponse assertion) { - PolicyResponse pape = assertion.GetExtension<PolicyResponse>(); - ErrorUtilities.VerifyProtocol( - pape != null && - pape.ActualPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1) && - pape.ActualPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier), - BehaviorStrings.PapeResponseOrRequiredPoliciesMissing); - - ErrorUtilities.VerifyProtocol(AllowPersonallyIdentifiableInformation || pape.ActualPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation), BehaviorStrings.PapeResponseOrRequiredPoliciesMissing); - - if (pape.ActualPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { - ErrorUtilities.VerifyProtocol( - assertion.GetExtension<ClaimsResponse>() == null && - assertion.GetExtension<FetchResponse>() == null, - BehaviorStrings.PiiIncludedWithNoPiiPolicy); - } - } - - #endregion - - #region IProviderBehavior Members - - /// <summary> - /// Adapts the default security settings to the requirements of this behavior. - /// </summary> - /// <param name="securitySettings">The original security settings.</param> - void IProviderBehavior.ApplySecuritySettings(ProviderSecuritySettings securitySettings) { - if (securitySettings.MaximumHashBitLength < 256) { - securitySettings.MaximumHashBitLength = 256; - } - - SetMaximumAssociationLifetimeToNotExceed(Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA256, MaximumAssociationLifetime, securitySettings); - SetMaximumAssociationLifetimeToNotExceed(Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, MaximumAssociationLifetime, securitySettings); - } - - /// <summary> - /// Called when a request is received by the Provider. - /// </summary> - /// <param name="request">The incoming request.</param> - /// <returns> - /// <c>true</c> if this behavior owns this request and wants to stop other behaviors - /// from handling it; <c>false</c> to allow other behaviors to process this request. - /// </returns> - /// <remarks> - /// Implementations may set a new value to <see cref="IRequest.SecuritySettings"/> but - /// should not change the properties on the instance of <see cref="ProviderSecuritySettings"/> - /// itself as that instance may be shared across many requests. - /// </remarks> - bool IProviderBehavior.OnIncomingRequest(IRequest request) { - var hostProcessedRequest = request as IHostProcessedRequest; - if (hostProcessedRequest != null) { - // Only apply our special policies if the RP requested it. - var papeRequest = request.GetExtension<PolicyRequest>(); - if (papeRequest != null) { - if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1)) { - // Whenever we see this GSA policy requested, we MUST also see the PPID policy requested. - ErrorUtilities.VerifyProtocol(papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier), BehaviorStrings.PapeRequestMissingRequiredPolicies); - ErrorUtilities.VerifyProtocol(string.Equals(hostProcessedRequest.Realm.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal) || DisableSslRequirement, BehaviorStrings.RealmMustBeHttps); - - // Apply GSA-specific security to this individual request. - request.SecuritySettings.RequireSsl = !DisableSslRequirement; - return true; - } - } - } - - return false; - } - - /// <summary> - /// Called when the Provider is preparing to send a response to an authentication request. - /// </summary> - /// <param name="request">The request that is configured to generate the outgoing response.</param> - /// <returns> - /// <c>true</c> if this behavior owns this request and wants to stop other behaviors - /// from handling it; <c>false</c> to allow other behaviors to process this request. - /// </returns> - bool IProviderBehavior.OnOutgoingResponse(Provider.IAuthenticationRequest request) { - bool result = false; - - // Nothing to do for negative assertions. - if (!request.IsAuthenticated.Value) { - return result; - } - - var requestInternal = (Provider.AuthenticationRequest)request; - var responseMessage = (IProtocolMessageWithExtensions)requestInternal.Response; - - // Only apply our special policies if the RP requested it. - var papeRequest = request.GetExtension<PolicyRequest>(); - if (papeRequest != null) { - var papeResponse = responseMessage.Extensions.OfType<PolicyResponse>().SingleOrDefault(); - if (papeResponse == null) { - request.AddResponseExtension(papeResponse = new PolicyResponse()); - } - - if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1)) { - result = true; - if (!papeResponse.ActualPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1)) { - papeResponse.ActualPolicies.Add(AuthenticationPolicies.USGovernmentTrustLevel1); - } - - // The spec requires that the OP perform discovery and if that fails, it must either sternly - // warn the user of a potential threat or just abort the authentication. - // We can't verify that the OP displayed anything to the user at this level, but we can - // at least verify that the OP performed the discovery on the realm and halt things if it didn't. - ErrorUtilities.VerifyHost(requestInternal.HasRealmDiscoveryBeenPerformed, BehaviorStrings.RealmDiscoveryNotPerformed); - } - - if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { - ErrorUtilities.VerifyProtocol(request.ClaimedIdentifier == request.LocalIdentifier, OpenIdStrings.DelegatingIdentifiersNotAllowed); - - // Mask the user's identity with a PPID. - ErrorUtilities.VerifyHost(PpidIdentifierProvider != null, BehaviorStrings.PpidProviderNotGiven); - Identifier ppidIdentifier = PpidIdentifierProvider.GetIdentifier(request.LocalIdentifier, request.Realm); - requestInternal.ResetClaimedAndLocalIdentifiers(ppidIdentifier); - - // Indicate that the RP is receiving a PPID claimed_id - if (!papeResponse.ActualPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { - papeResponse.ActualPolicies.Add(AuthenticationPolicies.PrivatePersonalIdentifier); - } - } - - if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { - ErrorUtilities.VerifyProtocol( - !responseMessage.Extensions.OfType<ClaimsResponse>().Any() && - !responseMessage.Extensions.OfType<FetchResponse>().Any(), - BehaviorStrings.PiiIncludedWithNoPiiPolicy); - - // If no PII is given in extensions, and the claimed_id is a PPID, then we can state we issue no PII. - if (papeResponse.ActualPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { - if (!papeResponse.ActualPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { - papeResponse.ActualPolicies.Add(AuthenticationPolicies.NoPersonallyIdentifiableInformation); - } - } - } - - Reporting.RecordEventOccurrence(this, "OP"); - } - - return result; - } - - #endregion - - /// <summary> - /// Ensures the maximum association lifetime does not exceed a given limit. - /// </summary> - /// <param name="associationType">Type of the association.</param> - /// <param name="maximumLifetime">The maximum lifetime.</param> - /// <param name="securitySettings">The security settings to adjust.</param> - private static void SetMaximumAssociationLifetimeToNotExceed(string associationType, TimeSpan maximumLifetime, ProviderSecuritySettings securitySettings) { - Contract.Requires(!String.IsNullOrEmpty(associationType)); - Contract.Requires(maximumLifetime.TotalSeconds > 0); - if (!securitySettings.AssociationLifetimes.ContainsKey(associationType) || - securitySettings.AssociationLifetimes[associationType] > maximumLifetime) { - securitySettings.AssociationLifetimes[associationType] = maximumLifetime; - } - } } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ExtensionsBindingElement.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ExtensionsBindingElement.cs index c516e8f..e7582c2 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ExtensionsBindingElement.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ExtensionsBindingElement.cs @@ -15,30 +15,26 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { using DotNetOpenAuth.Messaging.Reflection; using DotNetOpenAuth.OpenId.Extensions; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// The binding element that serializes/deserializes OpenID extensions to/from /// their carrying OpenID messages. /// </summary> internal class ExtensionsBindingElement : IChannelBindingElement { - /// <summary> - /// The security settings that apply to this relying party, if it is a relying party. - /// </summary> - private readonly RelyingPartySecuritySettings relyingPartySecuritySettings; + private readonly bool receiveUnsignedExtensions; /// <summary> /// Initializes a new instance of the <see cref="ExtensionsBindingElement"/> class. /// </summary> /// <param name="extensionFactory">The extension factory.</param> /// <param name="securitySettings">The security settings.</param> - internal ExtensionsBindingElement(IOpenIdExtensionFactory extensionFactory, SecuritySettings securitySettings) { + /// <param name="receiveUnsignedExtensions">Security setting for relying parties. Should be true for Providers.</param> + internal ExtensionsBindingElement(IOpenIdExtensionFactory extensionFactory, SecuritySettings securitySettings, bool receiveUnsignedExtensions) { Contract.Requires<ArgumentNullException>(extensionFactory != null); Contract.Requires<ArgumentNullException>(securitySettings != null); this.ExtensionFactory = extensionFactory; - this.relyingPartySecuritySettings = securitySettings as RelyingPartySecuritySettings; + this.receiveUnsignedExtensions = receiveUnsignedExtensions; } #region IChannelBindingElement Members @@ -156,7 +152,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { // Now search again, considering ALL extensions whether they are signed or not, // skipping the signed ones and adding the new ones as unsigned extensions. - if (this.relyingPartySecuritySettings == null || !this.relyingPartySecuritySettings.IgnoreUnsignedExtensions) { + if (this.receiveUnsignedExtensions) { Func<string, bool> isNotSigned = typeUri => !extendableMessage.Extensions.Cast<IOpenIdMessageExtension>().Any(ext => ext.TypeUri == typeUri); foreach (IOpenIdMessageExtension unsignedExtension in this.GetExtensions(extendableMessage, false, isNotSigned)) { Reporting.RecordFeatureUse(unsignedExtension); diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/IOpenIdExtensionFactory.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/IOpenIdExtensionFactory.cs index 762fc9a..31223a0 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/IOpenIdExtensionFactory.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/IOpenIdExtensionFactory.cs @@ -8,8 +8,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { using System.Collections.Generic; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// OpenID extension factory class for creating extensions based on received Type URIs. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdChannel.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdChannel.cs index d9a0e50..2f1c7da 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdChannel.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdChannel.cs @@ -18,8 +18,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OpenId.Extensions; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// A channel that knows how to send and receive OpenID messages. @@ -43,62 +41,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { private KeyValueFormEncoding keyValueForm = new KeyValueFormEncoding(); /// <summary> - /// Initializes a new instance of the <see cref="OpenIdChannel"/> class - /// for use by a Relying Party. - /// </summary> - /// <param name="cryptoKeyStore">The association store to use.</param> - /// <param name="nonceStore">The nonce store to use.</param> - /// <param name="securitySettings">The security settings to apply.</param> - internal OpenIdChannel(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore, RelyingPartySecuritySettings securitySettings) - : this(cryptoKeyStore, nonceStore, new OpenIdMessageFactory(), securitySettings, false) { - Contract.Requires<ArgumentNullException>(securitySettings != null); - } - - /// <summary> - /// Initializes a new instance of the <see cref="OpenIdChannel"/> class - /// for use by a Provider. - /// </summary> - /// <param name="cryptoKeyStore">The OpenID Provider's association store or handle encoder.</param> - /// <param name="nonceStore">The nonce store to use.</param> - /// <param name="securitySettings">The security settings.</param> - internal OpenIdChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings) - : this(cryptoKeyStore, nonceStore, new OpenIdMessageFactory(), securitySettings) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); - Contract.Requires<ArgumentNullException>(securitySettings != null); - } - - /// <summary> - /// Initializes a new instance of the <see cref="OpenIdChannel"/> class - /// for use by a Relying Party. - /// </summary> - /// <param name="cryptoKeyStore">The association store to use.</param> - /// <param name="nonceStore">The nonce store to use.</param> - /// <param name="messageTypeProvider">An object that knows how to distinguish the various OpenID message types for deserialization purposes.</param> - /// <param name="securitySettings">The security settings to apply.</param> - /// <param name="nonVerifying">A value indicating whether the channel is set up with no functional security binding elements.</param> - private OpenIdChannel(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, RelyingPartySecuritySettings securitySettings, bool nonVerifying) : - this(messageTypeProvider, InitializeBindingElements(cryptoKeyStore, nonceStore, securitySettings, nonVerifying)) { - Contract.Requires<ArgumentNullException>(messageTypeProvider != null); - Contract.Requires<ArgumentNullException>(securitySettings != null); - Contract.Requires<ArgumentException>(!nonVerifying || securitySettings is RelyingPartySecuritySettings); - } - - /// <summary> - /// Initializes a new instance of the <see cref="OpenIdChannel"/> class - /// for use by a Provider. - /// </summary> - /// <param name="cryptoKeyStore">The association store to use.</param> - /// <param name="nonceStore">The nonce store to use.</param> - /// <param name="messageTypeProvider">An object that knows how to distinguish the various OpenID message types for deserialization purposes.</param> - /// <param name="securitySettings">The security settings.</param> - private OpenIdChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, ProviderSecuritySettings securitySettings) : - this(messageTypeProvider, InitializeBindingElements(cryptoKeyStore, nonceStore, securitySettings)) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); - Contract.Requires<ArgumentNullException>(messageTypeProvider != null); - Contract.Requires<ArgumentNullException>(securitySettings != null); - } - - /// <summary> /// Initializes a new instance of the <see cref="OpenIdChannel"/> class. /// </summary> /// <param name="messageTypeProvider">A class prepared to analyze incoming messages and indicate what concrete @@ -135,24 +77,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { } /// <summary> - /// A value indicating whether the channel is set up - /// with no functional security binding elements. - /// </summary> - /// <returns>A new <see cref="OpenIdChannel"/> instance that will not perform verification on incoming messages or apply any security to outgoing messages.</returns> - /// <remarks> - /// <para>A value of <c>true</c> allows the relying party to preview incoming - /// messages without invalidating nonces or checking signatures.</para> - /// <para>Setting this to <c>true</c> poses a great security risk and is only - /// present to support the <see cref="OpenIdAjaxTextBox"/> which needs to preview - /// messages, and will validate them later.</para> - /// </remarks> - internal static OpenIdChannel CreateNonVerifyingChannel() { - Contract.Ensures(Contract.Result<OpenIdChannel>() != null); - - return new OpenIdChannel(null, null, new OpenIdMessageFactory(), new RelyingPartySecuritySettings(), true); - } - - /// <summary> /// Verifies the integrity and applicability of an incoming message. /// </summary> /// <param name="message">The message just received.</param> @@ -300,87 +224,5 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { return response; } - - /// <summary> - /// Initializes the binding elements. - /// </summary> - /// <param name="cryptoKeyStore">The crypto key store.</param> - /// <param name="nonceStore">The nonce store to use.</param> - /// <param name="securitySettings">The security settings to apply. Must be an instance of either <see cref="RelyingPartySecuritySettings"/> or <see cref="ProviderSecuritySettings"/>.</param> - /// <param name="nonVerifying">A value indicating whether the channel is set up with no functional security binding elements.</param> - /// <returns> - /// An array of binding elements which may be used to construct the channel. - /// </returns> - private static IChannelBindingElement[] InitializeBindingElements(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore, RelyingPartySecuritySettings securitySettings, bool nonVerifying) { - Contract.Requires<ArgumentNullException>(securitySettings != null); - - SigningBindingElement signingElement; - signingElement = nonVerifying ? null : new SigningBindingElement(new CryptoKeyStoreAsRelyingPartyAssociationStore(cryptoKeyStore ?? new MemoryCryptoKeyStore())); - - var extensionFactory = OpenIdExtensionFactoryAggregator.LoadFromConfiguration(); - - List<IChannelBindingElement> elements = new List<IChannelBindingElement>(8); - elements.Add(new ExtensionsBindingElement(extensionFactory, securitySettings)); - elements.Add(new RelyingPartySecurityOptions(securitySettings)); - elements.Add(new BackwardCompatibilityBindingElement()); - ReturnToNonceBindingElement requestNonceElement = null; - - if (cryptoKeyStore != null) { - if (nonceStore != null) { - // There is no point in having a ReturnToNonceBindingElement without - // a ReturnToSignatureBindingElement because the nonce could be - // artificially changed without it. - requestNonceElement = new ReturnToNonceBindingElement(nonceStore, securitySettings); - elements.Add(requestNonceElement); - } - - // It is important that the return_to signing element comes last - // so that the nonce is included in the signature. - elements.Add(new ReturnToSignatureBindingElement(cryptoKeyStore)); - } - - ErrorUtilities.VerifyOperation(!securitySettings.RejectUnsolicitedAssertions || requestNonceElement != null, OpenIdStrings.UnsolicitedAssertionRejectionRequiresNonceStore); - - if (nonVerifying) { - elements.Add(new SkipSecurityBindingElement()); - } else { - if (nonceStore != null) { - elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true)); - } - - elements.Add(new StandardExpirationBindingElement()); - elements.Add(signingElement); - } - - return elements.ToArray(); - } - - /// <summary> - /// Initializes the binding elements. - /// </summary> - /// <param name="cryptoKeyStore">The OpenID Provider's crypto key store.</param> - /// <param name="nonceStore">The nonce store to use.</param> - /// <param name="securitySettings">The security settings to apply. Must be an instance of either <see cref="RelyingPartySecuritySettings"/> or <see cref="ProviderSecuritySettings"/>.</param> - /// <returns> - /// An array of binding elements which may be used to construct the channel. - /// </returns> - private static IChannelBindingElement[] InitializeBindingElements(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); - Contract.Requires<ArgumentNullException>(securitySettings != null); - Contract.Requires<ArgumentNullException>(nonceStore != null); - - SigningBindingElement signingElement; - signingElement = new SigningBindingElement(cryptoKeyStore, securitySettings); - - var extensionFactory = OpenIdExtensionFactoryAggregator.LoadFromConfiguration(); - - List<IChannelBindingElement> elements = new List<IChannelBindingElement>(8); - elements.Add(new ExtensionsBindingElement(extensionFactory, securitySettings)); - elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true)); - elements.Add(new StandardExpirationBindingElement()); - elements.Add(signingElement); - - return elements.ToArray(); - } } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdMessageFactory.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdMessageFactory.cs index 1e5ea4c..98bbffa 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdMessageFactory.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdMessageFactory.cs @@ -12,7 +12,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { using System.Text; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// Distinguishes the various OpenID message types for deserialization purposes. @@ -120,7 +119,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { var associateUnencryptedRequest = request as AssociateUnencryptedRequest; if (associateDiffieHellmanRequest != null) { - message = new AssociateDiffieHellmanResponse(protocol.Version, associateDiffieHellmanRequest); + ////message = new AssociateDiffieHellmanResponse(protocol.Version, associateDiffieHellmanRequest); } if (associateUnencryptedRequest != null) { diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs index 15b6fc4..d47ba8b 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs @@ -15,8 +15,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.RelyingParty; - + /// <summary> /// This binding element signs a Relying Party's openid.return_to parameter /// so that upon return, it can verify that it hasn't been tampered with. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElement.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElement.cs index e301a3e..0041da4 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElement.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElement.cs @@ -18,50 +18,11 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.Messaging.Reflection; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// Signs and verifies authentication assertions. /// </summary> - internal class SigningBindingElement : IChannelBindingElement { - /// <summary> - /// The association store used by Relying Parties to look up the secrets needed for signing. - /// </summary> - private readonly IRelyingPartyAssociationStore rpAssociations; - - /// <summary> - /// The association store used by Providers to look up the secrets needed for signing. - /// </summary> - private readonly IProviderAssociationStore opAssociations; - - /// <summary> - /// The security settings at the Provider. - /// Only defined when this element is instantiated to service a Provider. - /// </summary> - private readonly ProviderSecuritySettings opSecuritySettings; - - /// <summary> - /// Initializes a new instance of the SigningBindingElement class for use by a Relying Party. - /// </summary> - /// <param name="associationStore">The association store used to look up the secrets needed for signing. May be null for dumb Relying Parties.</param> - internal SigningBindingElement(IRelyingPartyAssociationStore associationStore) { - this.rpAssociations = associationStore; - } - - /// <summary> - /// Initializes a new instance of the SigningBindingElement class for use by a Provider. - /// </summary> - /// <param name="associationStore">The association store used to look up the secrets needed for signing.</param> - /// <param name="securitySettings">The security settings.</param> - internal SigningBindingElement(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(associationStore != null); - Contract.Requires<ArgumentNullException>(securitySettings != null); - - this.opAssociations = associationStore; - this.opSecuritySettings = securitySettings; - } - + internal abstract class SigningBindingElement : IChannelBindingElement { #region IChannelBindingElement Properties /// <summary> @@ -82,8 +43,8 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// <summary> /// Gets a value indicating whether this binding element is on a Provider channel. /// </summary> - private bool IsOnProvider { - get { return this.opSecuritySettings != null; } + protected virtual bool IsOnProvider { + get { return false; } } #region IChannelBindingElement Methods @@ -96,17 +57,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// The protections (if any) that this binding element applied to the message. /// Null if this binding element did not even apply to this binding element. /// </returns> - public MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) { - var signedMessage = message as ITamperResistantOpenIdMessage; - if (signedMessage != null) { - Logger.Bindings.DebugFormat("Signing {0} message.", message.GetType().Name); - Association association = this.GetAssociation(signedMessage); - signedMessage.AssociationHandle = association.Handle; - signedMessage.SignedParameterOrder = this.GetSignedParameterOrder(signedMessage); - signedMessage.Signature = this.GetSignature(signedMessage, association); - return MessageProtections.TamperProtection; - } - + public virtual MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) { return null; } @@ -141,35 +92,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { } else { ErrorUtilities.VerifyInternal(this.Channel != null, "Cannot verify private association signature because we don't have a channel."); - // If we're on the Provider, then the RP sent us a check_auth with a signature - // we don't have an association for. (It may have expired, or it may be a faulty RP). - if (this.IsOnProvider) { - throw new InvalidSignatureException(message); - } - - // We did not recognize the association the provider used to sign the message. - // Ask the provider to check the signature then. - var indirectSignedResponse = (IndirectSignedResponse)signedMessage; - var checkSignatureRequest = new CheckAuthenticationRequest(indirectSignedResponse, this.Channel); - var checkSignatureResponse = this.Channel.Request<CheckAuthenticationResponse>(checkSignatureRequest); - if (!checkSignatureResponse.IsValid) { - Logger.Bindings.Error("Provider reports signature verification failed."); - throw new InvalidSignatureException(message); - } - - // If the OP confirms that a handle should be invalidated as well, do that. - if (!string.IsNullOrEmpty(checkSignatureResponse.InvalidateHandle)) { - if (this.rpAssociations != null) { - this.rpAssociations.RemoveAssociation(indirectSignedResponse.ProviderEndpoint, checkSignatureResponse.InvalidateHandle); - } - } - - // When we're in dumb mode we can't provide our own replay protection, - // but for OpenID 2.0 Providers we can rely on them providing it as part - // of signature verification. - if (message.Version.Major >= 2) { - protectionsApplied |= MessageProtections.ReplayProtection; - } + protectionsApplied = this.VerifySignatureByUnrecognizedHandle(message, signedMessage, protectionsApplied); } return protectionsApplied; @@ -178,48 +101,9 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { return null; } - #endregion - - /// <summary> - /// Determines whether the relying party sending an authentication request is - /// vulnerable to replay attacks. - /// </summary> - /// <param name="request">The request message from the Relying Party. Useful, but may be null for conservative estimate results.</param> - /// <param name="response">The response message to be signed.</param> - /// <returns> - /// <c>true</c> if the relying party is vulnerable; otherwise, <c>false</c>. - /// </returns> - private static bool IsRelyingPartyVulnerableToReplays(SignedResponseRequest request, IndirectSignedResponse response) { - Contract.Requires<ArgumentNullException>(response != null); - - // OpenID 2.0 includes replay protection as part of the protocol. - if (response.Version.Major >= 2) { - return false; - } + protected abstract MessageProtections VerifySignatureByUnrecognizedHandle(IProtocolMessage message, ITamperResistantOpenIdMessage signedMessage, MessageProtections protectionsApplied); - // This library's RP may be on the remote end, and may be using 1.x merely because - // discovery on the Claimed Identifier suggested this was a 1.x OP. - // Since this library's RP has a built-in request_nonce parameter for replay - // protection, we'll allow for that. - var returnToArgs = HttpUtility.ParseQueryString(response.ReturnTo.Query); - if (!string.IsNullOrEmpty(returnToArgs[ReturnToNonceBindingElement.NonceParameter])) { - return false; - } - - // If the OP endpoint _AND_ RP return_to URL uses HTTPS then no one - // can steal and replay the positive assertion. - // We can only ascertain this if the request message was handed to us - // so we know what our own OP endpoint is. If we don't have a request - // message, then we'll default to assuming it's insecure. - if (request != null) { - if (request.Recipient.IsTransportSecure() && response.Recipient.IsTransportSecure()) { - return false; - } - } - - // Nothing left to protect against replays. RP is vulnerable. - return true; - } + #endregion /// <summary> /// Ensures that all message parameters that must be signed are in fact included @@ -249,7 +133,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// <param name="signedMessage">The message to sign or verify.</param> /// <param name="association">The association to use to sign the message.</param> /// <returns>The calculated signature of the method.</returns> - private string GetSignature(ITamperResistantOpenIdMessage signedMessage, Association association) { + protected string GetSignature(ITamperResistantOpenIdMessage signedMessage, Association association) { Contract.Requires<ArgumentNullException>(signedMessage != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(signedMessage.SignedParameterOrder)); Contract.Requires<ArgumentNullException>(association != null); @@ -277,86 +161,11 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { } /// <summary> - /// Gets the value to use for the openid.signed parameter. - /// </summary> - /// <param name="signedMessage">The signable message.</param> - /// <returns> - /// A comma-delimited list of parameter names, omitting the 'openid.' prefix, that determines - /// the inclusion and order of message parts that will be signed. - /// </returns> - private string GetSignedParameterOrder(ITamperResistantOpenIdMessage signedMessage) { - Contract.Requires<InvalidOperationException>(this.Channel != null); - Contract.Requires<ArgumentNullException>(signedMessage != null); - - Protocol protocol = Protocol.Lookup(signedMessage.Version); - - MessageDescription description = this.Channel.MessageDescriptions.Get(signedMessage); - var signedParts = from part in description.Mapping.Values - where (part.RequiredProtection & System.Net.Security.ProtectionLevel.Sign) != 0 - && part.GetValue(signedMessage) != null - select part.Name; - string prefix = Protocol.V20.openid.Prefix; - ErrorUtilities.VerifyInternal(signedParts.All(name => name.StartsWith(prefix, StringComparison.Ordinal)), "All signed message parts must start with 'openid.'."); - - if (this.opSecuritySettings.SignOutgoingExtensions) { - // Tack on any ExtraData parameters that start with 'openid.'. - List<string> extraSignedParameters = new List<string>(signedMessage.ExtraData.Count); - foreach (string key in signedMessage.ExtraData.Keys) { - if (key.StartsWith(protocol.openid.Prefix, StringComparison.Ordinal)) { - extraSignedParameters.Add(key); - } else { - Logger.Signatures.DebugFormat("The extra parameter '{0}' will not be signed because it does not start with 'openid.'.", key); - } - } - signedParts = signedParts.Concat(extraSignedParameters); - } - - int skipLength = prefix.Length; - string signedFields = string.Join(",", signedParts.Select(name => name.Substring(skipLength)).ToArray()); - return signedFields; - } - - /// <summary> /// Gets the association to use to sign or verify a message. /// </summary> /// <param name="signedMessage">The message to sign or verify.</param> /// <returns>The association to use to sign or verify the message.</returns> - private Association GetAssociation(ITamperResistantOpenIdMessage signedMessage) { - Contract.Requires<ArgumentNullException>(signedMessage != null); - - if (this.IsOnProvider) { - // We're on a Provider to either sign (smart/dumb) or verify a dumb signature. - bool signing = string.IsNullOrEmpty(signedMessage.Signature); - - if (signing) { - // If the RP has no replay protection, coerce use of a private association - // instead of a shared one (if security settings indicate) - // to protect the authenticating user from replay attacks. - bool forcePrivateAssociation = this.opSecuritySettings.ProtectDownlevelReplayAttacks - && IsRelyingPartyVulnerableToReplays(null, (IndirectSignedResponse)signedMessage); - - if (forcePrivateAssociation) { - if (!string.IsNullOrEmpty(signedMessage.AssociationHandle)) { - Logger.Signatures.Info("An OpenID 1.x authentication request with a shared association handle will be responded to with a private association in order to provide OP-side replay protection."); - } - - return this.GetDumbAssociationForSigning(); - } else { - return this.GetSpecificAssociation(signedMessage) ?? this.GetDumbAssociationForSigning(); - } - } else { - return this.GetSpecificAssociation(signedMessage); - } - } else { - // We're on a Relying Party verifying a signature. - IDirectedProtocolMessage directedMessage = (IDirectedProtocolMessage)signedMessage; - if (this.rpAssociations != null) { - return this.rpAssociations.GetAssociation(directedMessage.Recipient, signedMessage.AssociationHandle); - } else { - return null; - } - } - } + protected abstract Association GetAssociation(ITamperResistantOpenIdMessage signedMessage); /// <summary> /// Gets a specific association referenced in a given message's association handle. @@ -369,42 +178,14 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// <see cref="ITamperResistantOpenIdMessage.InvalidateHandle"/> property is set to the /// handle that could not be found. /// </remarks> - private Association GetSpecificAssociation(ITamperResistantOpenIdMessage signedMessage) { - Association association = null; - - if (!string.IsNullOrEmpty(signedMessage.AssociationHandle)) { - IndirectSignedResponse indirectSignedMessage = signedMessage as IndirectSignedResponse; - if (this.IsOnProvider) { - // Since we have an association handle, we're either signing with a smart association, - // or verifying a dumb one. - bool signing = string.IsNullOrEmpty(signedMessage.Signature); - bool isPrivateAssociation = !signing; - association = this.opAssociations.Deserialize(signedMessage, isPrivateAssociation, signedMessage.AssociationHandle); - if (association == null) { - // There was no valid association with the requested handle. - // Let's tell the RP to forget about that association. - signedMessage.InvalidateHandle = signedMessage.AssociationHandle; - signedMessage.AssociationHandle = null; - } - } else if (this.rpAssociations != null) { // if on a smart RP - Uri providerEndpoint = indirectSignedMessage.ProviderEndpoint; - association = this.rpAssociations.GetAssociation(providerEndpoint, signedMessage.AssociationHandle); - } - } - - return association; - } + protected abstract Association GetSpecificAssociation(ITamperResistantOpenIdMessage signedMessage); /// <summary> /// Gets a private Provider association used for signing messages in "dumb" mode. /// </summary> /// <returns>An existing or newly created association.</returns> - private Association GetDumbAssociationForSigning() { - // If no assoc_handle was given or it was invalid, the only thing - // left to do is sign a message using a 'dumb' mode association. - Protocol protocol = Protocol.Default; - Association association = HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.HMAC_SHA256, AssociationRelyingPartyType.Dumb, this.opAssociations, this.opSecuritySettings); - return association; + protected virtual Association GetDumbAssociationForSigning() { + throw new NotImplementedException(); } } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionsInteropHelper.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionsInteropHelper.cs index 5e1003a..bd8117d 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionsInteropHelper.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionsInteropHelper.cs @@ -19,276 +19,50 @@ namespace DotNetOpenAuth.OpenId.Extensions { /// A set of methods designed to assist in improving interop across different /// OpenID implementations and their extensions. /// </summary> - public static class ExtensionsInteropHelper { + internal static class ExtensionsInteropHelper { /// <summary> /// The gender decoder to translate AX genders to Sreg. /// </summary> - private static GenderEncoder genderEncoder = new GenderEncoder(); + internal static GenderEncoder genderEncoder = new GenderEncoder(); /// <summary> - /// Adds an Attribute Exchange (AX) extension to the authentication request - /// that asks for the same attributes as the Simple Registration (sreg) extension - /// that is already applied. - /// </summary> - /// <param name="request">The authentication request.</param> - /// <param name="attributeFormats">The attribute formats to use in the AX request.</param> - /// <remarks> - /// <para>If discovery on the user-supplied identifier yields hints regarding which - /// extensions and attribute formats the Provider supports, this method MAY ignore the - /// <paramref name="attributeFormats"/> argument and accomodate the Provider to minimize - /// the size of the request.</para> - /// <para>If the request does not carry an sreg extension, the method logs a warning but - /// otherwise quietly returns doing nothing.</para> - /// </remarks> - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Abbreviation")] - public static void SpreadSregToAX(this RelyingParty.IAuthenticationRequest request, AXAttributeFormats attributeFormats) { - Contract.Requires<ArgumentNullException>(request != null); - - var req = (RelyingParty.AuthenticationRequest)request; - var sreg = req.AppliedExtensions.OfType<ClaimsRequest>().SingleOrDefault(); - if (sreg == null) { - Logger.OpenId.Debug("No Simple Registration (ClaimsRequest) extension present in the request to spread to AX."); - return; - } - - if (req.DiscoveryResult.IsExtensionSupported<ClaimsRequest>()) { - Logger.OpenId.Debug("Skipping generation of AX request because the Identifier advertises the Provider supports the Sreg extension."); - return; - } - - var ax = req.AppliedExtensions.OfType<FetchRequest>().SingleOrDefault(); - if (ax == null) { - ax = new FetchRequest(); - req.AddExtension(ax); - } - - // Try to use just one AX Type URI format if we can figure out which type the OP accepts. - AXAttributeFormats detectedFormat; - if (TryDetectOPAttributeFormat(request, out detectedFormat)) { - Logger.OpenId.Debug("Detected OP support for AX but not for Sreg. Removing Sreg extension request and using AX instead."); - attributeFormats = detectedFormat; - req.Extensions.Remove(sreg); - } else { - Logger.OpenId.Debug("Could not determine whether OP supported Sreg or AX. Using both extensions."); - } - - foreach (AXAttributeFormats format in ForEachFormat(attributeFormats)) { - FetchAttribute(ax, format, WellKnownAttributes.BirthDate.WholeBirthDate, sreg.BirthDate); - FetchAttribute(ax, format, WellKnownAttributes.Contact.HomeAddress.Country, sreg.Country); - FetchAttribute(ax, format, WellKnownAttributes.Contact.Email, sreg.Email); - FetchAttribute(ax, format, WellKnownAttributes.Name.FullName, sreg.FullName); - FetchAttribute(ax, format, WellKnownAttributes.Person.Gender, sreg.Gender); - FetchAttribute(ax, format, WellKnownAttributes.Preferences.Language, sreg.Language); - FetchAttribute(ax, format, WellKnownAttributes.Name.Alias, sreg.Nickname); - FetchAttribute(ax, format, WellKnownAttributes.Contact.HomeAddress.PostalCode, sreg.PostalCode); - FetchAttribute(ax, format, WellKnownAttributes.Preferences.TimeZone, sreg.TimeZone); - } - } - - /// <summary> - /// Looks for Simple Registration and Attribute Exchange (all known formats) - /// response extensions and returns them as a Simple Registration extension. - /// </summary> - /// <param name="response">The authentication response.</param> - /// <param name="allowUnsigned">if set to <c>true</c> unsigned extensions will be included in the search.</param> - /// <returns> - /// The Simple Registration response if found, - /// or a fabricated one based on the Attribute Exchange extension if found, - /// or just an empty <see cref="ClaimsResponse"/> if there was no data. - /// Never <c>null</c>.</returns> - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Abbreviation")] - public static ClaimsResponse UnifyExtensionsAsSreg(this RelyingParty.IAuthenticationResponse response, bool allowUnsigned) { - Contract.Requires<ArgumentNullException>(response != null); - - var resp = (RelyingParty.IAuthenticationResponse)response; - var sreg = allowUnsigned ? resp.GetUntrustedExtension<ClaimsResponse>() : resp.GetExtension<ClaimsResponse>(); - if (sreg != null) { - return sreg; - } - - AXAttributeFormats formats = AXAttributeFormats.All; - sreg = new ClaimsResponse(); - var fetchResponse = allowUnsigned ? resp.GetUntrustedExtension<FetchResponse>() : resp.GetExtension<FetchResponse>(); - if (fetchResponse != null) { - ((IOpenIdMessageExtension)sreg).IsSignedByRemoteParty = fetchResponse.IsSignedByProvider; - sreg.BirthDateRaw = fetchResponse.GetAttributeValue(WellKnownAttributes.BirthDate.WholeBirthDate, formats); - sreg.Country = fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.HomeAddress.Country, formats); - sreg.PostalCode = fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.HomeAddress.PostalCode, formats); - sreg.Email = fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.Email, formats); - sreg.FullName = fetchResponse.GetAttributeValue(WellKnownAttributes.Name.FullName, formats); - sreg.Language = fetchResponse.GetAttributeValue(WellKnownAttributes.Preferences.Language, formats); - sreg.Nickname = fetchResponse.GetAttributeValue(WellKnownAttributes.Name.Alias, formats); - sreg.TimeZone = fetchResponse.GetAttributeValue(WellKnownAttributes.Preferences.TimeZone, formats); - string gender = fetchResponse.GetAttributeValue(WellKnownAttributes.Person.Gender, formats); - if (gender != null) { - sreg.Gender = (Gender)genderEncoder.Decode(gender); - } - } - - return sreg; - } - - /// <summary> - /// Looks for Simple Registration and Attribute Exchange (all known formats) - /// request extensions and returns them as a Simple Registration extension, - /// and adds the new extension to the original request message if it was absent. + /// Splits the AX attribute format flags into individual values for processing. /// </summary> - /// <param name="request">The authentication request.</param> - /// <returns> - /// The Simple Registration request if found, - /// or a fabricated one based on the Attribute Exchange extension if found, - /// or <c>null</c> if no attribute extension request is found.</returns> - internal static ClaimsRequest UnifyExtensionsAsSreg(this Provider.IHostProcessedRequest request) { - Contract.Requires<ArgumentNullException>(request != null); - - var req = (Provider.HostProcessedRequest)request; - var sreg = req.GetExtension<ClaimsRequest>(); - if (sreg != null) { - return sreg; + /// <param name="formats">The formats to split up into individual flags.</param> + /// <returns>A sequence of individual flags.</returns> + internal static IEnumerable<AXAttributeFormats> ForEachFormat(AXAttributeFormats formats) { + if ((formats & AXAttributeFormats.AXSchemaOrg) != 0) { + yield return AXAttributeFormats.AXSchemaOrg; } - var ax = req.GetExtension<FetchRequest>(); - if (ax != null) { - sreg = new ClaimsRequest(SimpleRegistration.Constants.sreg_ns); - sreg.Synthesized = true; - ((IProtocolMessageWithExtensions)req.RequestMessage).Extensions.Add(sreg); - sreg.BirthDate = GetDemandLevelFor(ax, WellKnownAttributes.BirthDate.WholeBirthDate); - sreg.Country = GetDemandLevelFor(ax, WellKnownAttributes.Contact.HomeAddress.Country); - sreg.Email = GetDemandLevelFor(ax, WellKnownAttributes.Contact.Email); - sreg.FullName = GetDemandLevelFor(ax, WellKnownAttributes.Name.FullName); - sreg.Gender = GetDemandLevelFor(ax, WellKnownAttributes.Person.Gender); - sreg.Language = GetDemandLevelFor(ax, WellKnownAttributes.Preferences.Language); - sreg.Nickname = GetDemandLevelFor(ax, WellKnownAttributes.Name.Alias); - sreg.PostalCode = GetDemandLevelFor(ax, WellKnownAttributes.Contact.HomeAddress.PostalCode); - sreg.TimeZone = GetDemandLevelFor(ax, WellKnownAttributes.Preferences.TimeZone); + if ((formats & AXAttributeFormats.OpenIdNetSchema) != 0) { + yield return AXAttributeFormats.OpenIdNetSchema; } - return sreg; - } - - /// <summary> - /// Converts the Simple Registration extension response to whatever format the original - /// attribute request extension came in. - /// </summary> - /// <param name="request">The authentication request with the response extensions already added.</param> - /// <remarks> - /// If the original attribute request came in as AX, the Simple Registration extension is converted - /// to an AX response and then the Simple Registration extension is removed from the response. - /// </remarks> - internal static void ConvertSregToMatchRequest(this Provider.IHostProcessedRequest request) { - var req = (Provider.HostProcessedRequest)request; - var response = req.Response as IProtocolMessageWithExtensions; // negative responses don't support extensions. - var sregRequest = request.GetExtension<ClaimsRequest>(); - if (sregRequest != null && response != null) { - if (sregRequest.Synthesized) { - var axRequest = request.GetExtension<FetchRequest>(); - ErrorUtilities.VerifyInternal(axRequest != null, "How do we have a synthesized Sreg request without an AX request?"); - - var sregResponse = response.Extensions.OfType<ClaimsResponse>().SingleOrDefault(); - if (sregResponse == null) { - // No Sreg response to copy from. - return; - } - - // Remove the sreg response since the RP didn't ask for it. - response.Extensions.Remove(sregResponse); - - AXAttributeFormats format = DetectAXFormat(axRequest.Attributes.Select(att => att.TypeUri)); - if (format == AXAttributeFormats.None) { - // No recognized AX attributes were requested. - return; - } - - var axResponse = response.Extensions.OfType<FetchResponse>().SingleOrDefault(); - if (axResponse == null) { - axResponse = new FetchResponse(); - response.Extensions.Add(axResponse); - } - - AddAXAttributeValue(axResponse, WellKnownAttributes.BirthDate.WholeBirthDate, format, sregResponse.BirthDateRaw); - AddAXAttributeValue(axResponse, WellKnownAttributes.Contact.HomeAddress.Country, format, sregResponse.Country); - AddAXAttributeValue(axResponse, WellKnownAttributes.Contact.HomeAddress.PostalCode, format, sregResponse.PostalCode); - AddAXAttributeValue(axResponse, WellKnownAttributes.Contact.Email, format, sregResponse.Email); - AddAXAttributeValue(axResponse, WellKnownAttributes.Name.FullName, format, sregResponse.FullName); - AddAXAttributeValue(axResponse, WellKnownAttributes.Name.Alias, format, sregResponse.Nickname); - AddAXAttributeValue(axResponse, WellKnownAttributes.Preferences.TimeZone, format, sregResponse.TimeZone); - AddAXAttributeValue(axResponse, WellKnownAttributes.Preferences.Language, format, sregResponse.Language); - if (sregResponse.Gender.HasValue) { - AddAXAttributeValue(axResponse, WellKnownAttributes.Person.Gender, format, genderEncoder.Encode(sregResponse.Gender)); - } - } + if ((formats & AXAttributeFormats.SchemaOpenIdNet) != 0) { + yield return AXAttributeFormats.SchemaOpenIdNet; } } /// <summary> - /// Gets the attribute value if available. - /// </summary> - /// <param name="fetchResponse">The AX fetch response extension to look for the attribute value.</param> - /// <param name="typeUri">The type URI of the attribute, using the axschema.org format of <see cref="WellKnownAttributes"/>.</param> - /// <param name="formats">The AX type URI formats to search.</param> - /// <returns> - /// The first value of the attribute, if available. - /// </returns> - internal static string GetAttributeValue(this FetchResponse fetchResponse, string typeUri, AXAttributeFormats formats) { - return ForEachFormat(formats).Select(format => fetchResponse.GetAttributeValue(TransformAXFormat(typeUri, format))).FirstOrDefault(s => s != null); - } - - /// <summary> /// Transforms an AX attribute type URI from the axschema.org format into a given format. /// </summary> /// <param name="axSchemaOrgFormatTypeUri">The ax schema org format type URI.</param> /// <param name="targetFormat">The target format. Only one flag should be set.</param> /// <returns>The AX attribute type URI in the target format.</returns> - internal static string TransformAXFormatTestHook(string axSchemaOrgFormatTypeUri, AXAttributeFormats targetFormat) { - return TransformAXFormat(axSchemaOrgFormatTypeUri, targetFormat); - } - - /// <summary> - /// Adds the AX attribute value to the response if it is non-empty. - /// </summary> - /// <param name="ax">The AX Fetch response to add the attribute value to.</param> - /// <param name="typeUri">The attribute type URI in axschema.org format.</param> - /// <param name="format">The target format of the actual attribute to write out.</param> - /// <param name="value">The value of the attribute.</param> - private static void AddAXAttributeValue(FetchResponse ax, string typeUri, AXAttributeFormats format, string value) { - if (!string.IsNullOrEmpty(value)) { - string targetTypeUri = TransformAXFormat(typeUri, format); - if (!ax.Attributes.Contains(targetTypeUri)) { - ax.Attributes.Add(targetTypeUri, value); - } - } - } - - /// <summary> - /// Gets the demand level for an AX attribute. - /// </summary> - /// <param name="ax">The AX fetch request to search for the attribute.</param> - /// <param name="typeUri">The type URI of the attribute in axschema.org format.</param> - /// <returns>The demand level for the attribute.</returns> - private static DemandLevel GetDemandLevelFor(FetchRequest ax, string typeUri) { - Contract.Requires<ArgumentNullException>(ax != null); - Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri)); + internal static string TransformAXFormat(string axSchemaOrgFormatTypeUri, AXAttributeFormats targetFormat) { + Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(axSchemaOrgFormatTypeUri)); - foreach (AXAttributeFormats format in ForEachFormat(AXAttributeFormats.All)) { - string typeUriInFormat = TransformAXFormat(typeUri, format); - if (ax.Attributes.Contains(typeUriInFormat)) { - return ax.Attributes[typeUriInFormat].IsRequired ? DemandLevel.Require : DemandLevel.Request; - } + switch (targetFormat) { + case AXAttributeFormats.AXSchemaOrg: + return axSchemaOrgFormatTypeUri; + case AXAttributeFormats.SchemaOpenIdNet: + return axSchemaOrgFormatTypeUri.Replace("axschema.org", "schema.openid.net"); + case AXAttributeFormats.OpenIdNetSchema: + return axSchemaOrgFormatTypeUri.Replace("axschema.org", "openid.net/schema"); + default: + throw new ArgumentOutOfRangeException("targetFormat"); } - - return DemandLevel.NoRequest; - } - - /// <summary> - /// Tries to find the exact format of AX attribute Type URI supported by the Provider. - /// </summary> - /// <param name="request">The authentication request.</param> - /// <param name="attributeFormat">The attribute formats the RP will try if this discovery fails.</param> - /// <returns>The AX format(s) to use based on the Provider's advertised AX support.</returns> - private static bool TryDetectOPAttributeFormat(RelyingParty.IAuthenticationRequest request, out AXAttributeFormats attributeFormat) { - Contract.Requires<ArgumentNullException>(request != null); - attributeFormat = DetectAXFormat(request.DiscoveryResult.Capabilities); - return attributeFormat != AXAttributeFormats.None; } /// <summary> @@ -296,7 +70,7 @@ namespace DotNetOpenAuth.OpenId.Extensions { /// </summary> /// <param name="typeURIs">The type URIs to scan for recognized formats.</param> /// <returns>The first AX type URI format recognized in the list.</returns> - private static AXAttributeFormats DetectAXFormat(IEnumerable<string> typeURIs) { + internal static AXAttributeFormats DetectAXFormat(IEnumerable<string> typeURIs) { Contract.Requires<ArgumentNullException>(typeURIs != null); if (typeURIs.Any(uri => uri.StartsWith("http://axschema.org/", StringComparison.Ordinal))) { @@ -315,53 +89,13 @@ namespace DotNetOpenAuth.OpenId.Extensions { } /// <summary> - /// Transforms an AX attribute type URI from the axschema.org format into a given format. - /// </summary> - /// <param name="axSchemaOrgFormatTypeUri">The ax schema org format type URI.</param> - /// <param name="targetFormat">The target format. Only one flag should be set.</param> - /// <returns>The AX attribute type URI in the target format.</returns> - private static string TransformAXFormat(string axSchemaOrgFormatTypeUri, AXAttributeFormats targetFormat) { - Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(axSchemaOrgFormatTypeUri)); - - switch (targetFormat) { - case AXAttributeFormats.AXSchemaOrg: - return axSchemaOrgFormatTypeUri; - case AXAttributeFormats.SchemaOpenIdNet: - return axSchemaOrgFormatTypeUri.Replace("axschema.org", "schema.openid.net"); - case AXAttributeFormats.OpenIdNetSchema: - return axSchemaOrgFormatTypeUri.Replace("axschema.org", "openid.net/schema"); - default: - throw new ArgumentOutOfRangeException("targetFormat"); - } - } - - /// <summary> - /// Splits the AX attribute format flags into individual values for processing. - /// </summary> - /// <param name="formats">The formats to split up into individual flags.</param> - /// <returns>A sequence of individual flags.</returns> - private static IEnumerable<AXAttributeFormats> ForEachFormat(AXAttributeFormats formats) { - if ((formats & AXAttributeFormats.AXSchemaOrg) != 0) { - yield return AXAttributeFormats.AXSchemaOrg; - } - - if ((formats & AXAttributeFormats.OpenIdNetSchema) != 0) { - yield return AXAttributeFormats.OpenIdNetSchema; - } - - if ((formats & AXAttributeFormats.SchemaOpenIdNet) != 0) { - yield return AXAttributeFormats.SchemaOpenIdNet; - } - } - - /// <summary> /// Adds an attribute fetch request if it is not already present in the AX request. /// </summary> /// <param name="ax">The AX request to add the attribute request to.</param> /// <param name="format">The format of the attribute's Type URI to use.</param> /// <param name="axSchemaOrgFormatAttribute">The attribute in axschema.org format.</param> /// <param name="demandLevel">The demand level.</param> - private static void FetchAttribute(FetchRequest ax, AXAttributeFormats format, string axSchemaOrgFormatAttribute, DemandLevel demandLevel) { + internal static void FetchAttribute(FetchRequest ax, AXAttributeFormats format, string axSchemaOrgFormatAttribute, DemandLevel demandLevel) { Contract.Requires<ArgumentNullException>(ax != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(axSchemaOrgFormatAttribute)); diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/IClientScriptExtensionResponse.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/IClientScriptExtensionResponse.cs index c84f507..38c1360 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/IClientScriptExtensionResponse.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/IClientScriptExtensionResponse.cs @@ -8,8 +8,7 @@ namespace DotNetOpenAuth.OpenId.Extensions { using System.Collections.Generic; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.RelyingParty; - + /// <summary> /// An interface that OpenID extensions can implement to allow authentication response /// messages with included extensions to be processed by Javascript on the user agent. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/UI/UIRequest.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/UI/UIRequest.cs index df36b5e..cf3054d 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/UI/UIRequest.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/UI/UIRequest.cs @@ -13,8 +13,6 @@ namespace DotNetOpenAuth.OpenId.Extensions.UI { using System.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Xrds; /// <summary> @@ -190,33 +188,33 @@ namespace DotNetOpenAuth.OpenId.Extensions.UI { } } - /// <summary> - /// Gets the URL of the RP icon for the OP to display. - /// </summary> - /// <param name="realm">The realm of the RP where the authentication request originated.</param> - /// <param name="provider">The Provider instance used to obtain the authentication request.</param> - /// <returns> - /// A sequence of the RP's icons it has available for the Provider to display, in decreasing preferred order. - /// </returns> - /// <value>The icon URL.</value> - /// <remarks> - /// This property is automatically set for the OP with the result of RP discovery. - /// RPs should set this value by including an entry such as this in their XRDS document. - /// <example> - /// <Service xmlns="xri://$xrd*($v*2.0)"> - /// <Type>http://specs.openid.net/extensions/ui/icon</Type> - /// <URI>http://consumer.example.com/images/image.jpg</URI> - /// </Service> - /// </example> - /// </remarks> - public static IEnumerable<Uri> GetRelyingPartyIconUrls(Realm realm, OpenIdProvider provider) { - Contract.Requires(realm != null); - Contract.Requires(provider != null); - ErrorUtilities.VerifyArgumentNotNull(realm, "realm"); - ErrorUtilities.VerifyArgumentNotNull(provider, "provider"); + /////// <summary> + /////// Gets the URL of the RP icon for the OP to display. + /////// </summary> + /////// <param name="realm">The realm of the RP where the authentication request originated.</param> + /////// <param name="provider">The Provider instance used to obtain the authentication request.</param> + /////// <returns> + /////// A sequence of the RP's icons it has available for the Provider to display, in decreasing preferred order. + /////// </returns> + /////// <value>The icon URL.</value> + /////// <remarks> + /////// This property is automatically set for the OP with the result of RP discovery. + /////// RPs should set this value by including an entry such as this in their XRDS document. + /////// <example> + /////// <Service xmlns="xri://$xrd*($v*2.0)"> + /////// <Type>http://specs.openid.net/extensions/ui/icon</Type> + /////// <URI>http://consumer.example.com/images/image.jpg</URI> + /////// </Service> + /////// </example> + /////// </remarks> + ////public static IEnumerable<Uri> GetRelyingPartyIconUrls(Realm realm, OpenIdProvider provider) { + //// Contract.Requires(realm != null); + //// Contract.Requires(provider != null); + //// ErrorUtilities.VerifyArgumentNotNull(realm, "realm"); + //// ErrorUtilities.VerifyArgumentNotNull(provider, "provider"); - return GetRelyingPartyIconUrls(realm, provider.Channel.WebRequestHandler); - } + //// return GetRelyingPartyIconUrls(realm, provider.Channel.WebRequestHandler); + ////} #region IMessage methods diff --git a/src/DotNetOpenAuth.OpenId/OpenId/HmacShaAssociation.cs b/src/DotNetOpenAuth.OpenId/OpenId/HmacShaAssociation.cs index 29da1be..6955f48 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/HmacShaAssociation.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/HmacShaAssociation.cs @@ -15,7 +15,6 @@ namespace DotNetOpenAuth.OpenId { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.Provider; /// <summary> /// An association that uses the HMAC-SHA family of algorithms for message signing. @@ -23,12 +22,6 @@ namespace DotNetOpenAuth.OpenId { [ContractVerification(true)] internal class HmacShaAssociation : Association { /// <summary> - /// The default lifetime of a shared association when no lifetime is given - /// for a specific association type. - /// </summary> - private static readonly TimeSpan DefaultMaximumLifetime = TimeSpan.FromDays(14); - - /// <summary> /// A list of HMAC-SHA algorithms in order of decreasing bit lengths. /// </summary> private static HmacSha[] hmacShaAssociationTypes = new List<HmacSha> { @@ -138,51 +131,6 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> - /// Creates a new association of a given type at an OpenID Provider. - /// </summary> - /// <param name="protocol">The protocol.</param> - /// <param name="associationType">Type of the association (i.e. HMAC-SHA1 or HMAC-SHA256)</param> - /// <param name="associationUse">A value indicating whether the new association will be used privately by the Provider for "dumb mode" authentication - /// or shared with the Relying Party for "smart mode" authentication.</param> - /// <param name="associationStore">The Provider's association store.</param> - /// <param name="securitySettings">The security settings of the Provider.</param> - /// <returns> - /// The newly created association. - /// </returns> - /// <remarks> - /// The new association is NOT automatically put into an association store. This must be done by the caller. - /// </remarks> - internal static HmacShaAssociation Create(Protocol protocol, string associationType, AssociationRelyingPartyType associationUse, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(protocol != null); - Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType)); - Contract.Requires<ArgumentNullException>(associationStore != null); - Contract.Requires<ArgumentNullException>(securitySettings != null); - Contract.Ensures(Contract.Result<HmacShaAssociation>() != null); - - int secretLength = GetSecretLength(protocol, associationType); - - // Generate the secret that will be used for signing - byte[] secret = MessagingUtilities.GetCryptoRandomData(secretLength); - - TimeSpan lifetime; - if (associationUse == AssociationRelyingPartyType.Smart) { - if (!securitySettings.AssociationLifetimes.TryGetValue(associationType, out lifetime)) { - lifetime = DefaultMaximumLifetime; - } - } else { - lifetime = DumbSecretLifetime; - } - - string handle = associationStore.Serialize(secret, DateTime.UtcNow + lifetime, associationUse == AssociationRelyingPartyType.Dumb); - - Contract.Assert(protocol != null); // All the way up to the method call, the condition holds, yet we get a Requires failure next - Contract.Assert(secret != null); - Contract.Assert(!String.IsNullOrEmpty(associationType)); - var result = Create(protocol, associationType, handle, secret, lifetime); - return result; - } - - /// <summary> /// Looks for the first association type in a preferred-order list that is /// likely to be supported given a specific OpenID version and the security settings, /// and perhaps a matching Diffie-Hellman session type. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Identifier.cs b/src/DotNetOpenAuth.OpenId/OpenId/Identifier.cs index 2d919ea..287a342 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Identifier.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Identifier.cs @@ -11,7 +11,6 @@ namespace DotNetOpenAuth.OpenId { using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Messaging.Reflection; /// <summary> diff --git a/src/DotNetOpenAuth.OpenId/OpenId/IdentifierContract.cs b/src/DotNetOpenAuth.OpenId/OpenId/IdentifierContract.cs index 4af18e1..7355491 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/IdentifierContract.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/IdentifierContract.cs @@ -9,7 +9,6 @@ namespace DotNetOpenAuth.OpenId { using System.Collections.Generic; using System.Diagnostics.Contracts; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// Code Contract for the <see cref="Identifier"/> class. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateDiffieHellmanRequest.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateDiffieHellmanRequest.cs index 01e23e4..43a554c 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateDiffieHellmanRequest.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateDiffieHellmanRequest.cs @@ -110,10 +110,10 @@ namespace DotNetOpenAuth.OpenId.Messages { /// <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(this.Version, this); - response.AssociationType = this.AssociationType; - return response; - } + ////protected /*override */ IProtocolMessage CreateResponseCore() { + //// var response = new AssociateDiffieHellmanResponse(this.Version, this); + //// response.AssociationType = this.AssociationType; + //// return response; + ////} } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateDiffieHellmanResponse.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateDiffieHellmanResponse.cs index 5237826..d1836ec 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateDiffieHellmanResponse.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateDiffieHellmanResponse.cs @@ -10,7 +10,6 @@ namespace DotNetOpenAuth.OpenId.Messages { using System.Security.Cryptography; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Reflection; - using DotNetOpenAuth.OpenId.Provider; using Org.Mentalis.Security.Cryptography; /// <summary> @@ -19,7 +18,7 @@ namespace DotNetOpenAuth.OpenId.Messages { /// <remarks> /// Association response messages are described in OpenID 2.0 section 8.2. This type covers section 8.2.3. /// </remarks> - internal class AssociateDiffieHellmanResponse : AssociateSuccessfulResponse { + internal abstract class AssociateDiffieHellmanResponse : AssociateSuccessfulResponse { /// <summary> /// Initializes a new instance of the <see cref="AssociateDiffieHellmanResponse"/> class. /// </summary> @@ -42,62 +41,5 @@ namespace DotNetOpenAuth.OpenId.Messages { /// <value>H(btwoc(g ^ (xa * xb) mod p)) XOR MAC key. H is either "SHA1" or "SHA256" depending on the session type. </value> [MessagePart("enc_mac_key", IsRequired = true, AllowEmpty = false)] internal byte[] EncodedMacKey { get; set; } - - /// <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> - /// <returns>The newly created association.</returns> - /// <remarks> - /// The resulting association is <i>not</i> added to the association store and must be done by the caller. - /// </remarks> - protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { - var diffieHellmanRequest = request as AssociateDiffieHellmanRequest; - ErrorUtilities.VerifyArgument(diffieHellmanRequest != null, OpenIdStrings.DiffieHellmanAssociationRequired); - - HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(Protocol, this.SessionType); - 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; - } - - /// <summary> - /// Creates the association at the provider side after the association request has been received. - /// </summary> - /// <param name="request">The association request.</param> - /// <param name="associationStore">The OpenID Provider's association store or handle encoder.</param> - /// <param name="securitySettings">The security settings of the Provider.</param> - /// <returns> - /// The newly created association. - /// </returns> - /// <remarks> - /// 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> - protected override Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { - var diffieHellmanRequest = request as AssociateDiffieHellmanRequest; - ErrorUtilities.VerifyInternal(diffieHellmanRequest != null, "Expected a DH request type."); - - this.SessionType = this.SessionType ?? request.SessionType; - - // Go ahead and create the association first, complete with its secret that we're about to share. - Association association = HmacShaAssociation.Create(this.Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings); - - // We now need to securely communicate the secret to the relying party using Diffie-Hellman. - // We do this by performing a DH algorithm on the secret and setting a couple of properties - // that will be transmitted to the Relying Party. The RP will perform an inverse operation - // using its part of a DH secret in order to decrypt the shared secret we just invented - // above when we created the association. - using (DiffieHellman dh = new DiffieHellmanManaged( - 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, diffieHellmanRequest.DiffieHellmanConsumerPublic, association.SecretKey); - } - return association; - } } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateRequest.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateRequest.cs index 2a0dc7a..db0c39e 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateRequest.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateRequest.cs @@ -12,8 +12,6 @@ namespace DotNetOpenAuth.OpenId.Messages { using System.Linq; using System.Text; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// An OpenID direct request from Relying Party to Provider to initiate an association. @@ -65,150 +63,5 @@ namespace DotNetOpenAuth.OpenId.Messages { OpenIdStrings.NoEncryptionSessionRequiresHttps, this); } - - /// <summary> - /// Creates an association request message that is appropriate for a given Provider. - /// </summary> - /// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param> - /// <param name="provider">The provider to create an association with.</param> - /// <returns> - /// The message to send to the Provider to request an association. - /// Null if no association could be created that meet the security requirements - /// and the provider OpenID version. - /// </returns> - internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider) { - Contract.Requires<ArgumentNullException>(securityRequirements != null); - Contract.Requires<ArgumentNullException>(provider != null); - - // Apply our knowledge of the endpoint's transport, OpenID version, and - // security requirements to decide the best association. - bool unencryptedAllowed = provider.Uri.IsTransportSecure(); - bool useDiffieHellman = !unencryptedAllowed; - string associationType, sessionType; - if (!HmacShaAssociation.TryFindBestAssociation(Protocol.Lookup(provider.Version), true, securityRequirements, useDiffieHellman, out associationType, out sessionType)) { - // There are no associations that meet all requirements. - Logger.OpenId.Warn("Security requirements and protocol combination knock out all possible association types. Dumb mode forced."); - return null; - } - - return Create(securityRequirements, provider, associationType, sessionType); - } - - /// <summary> - /// Creates an association request message that is appropriate for a given Provider. - /// </summary> - /// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param> - /// <param name="provider">The provider to create an association with.</param> - /// <param name="associationType">Type of the association.</param> - /// <param name="sessionType">Type of the session.</param> - /// <returns> - /// The message to send to the Provider to request an association. - /// Null if no association could be created that meet the security requirements - /// and the provider OpenID version. - /// </returns> - internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider, string associationType, string sessionType) { - Contract.Requires<ArgumentNullException>(securityRequirements != null); - Contract.Requires<ArgumentNullException>(provider != null); - Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType)); - Contract.Requires<ArgumentNullException>(sessionType != null); - - bool unencryptedAllowed = provider.Uri.IsTransportSecure(); - if (unencryptedAllowed) { - var associateRequest = new AssociateUnencryptedRequest(provider.Version, provider.Uri); - associateRequest.AssociationType = associationType; - return associateRequest; - } else { - var associateRequest = new AssociateDiffieHellmanRequest(provider.Version, provider.Uri); - associateRequest.AssociationType = associationType; - associateRequest.SessionType = sessionType; - associateRequest.InitializeRequest(); - return associateRequest; - } - } - - /// <summary> - /// Creates a Provider's response to an incoming association request. - /// </summary> - /// <param name="associationStore">The association store.</param> - /// <param name="securitySettings">The security settings on the Provider.</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(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(associationStore != null); - Contract.Requires<ArgumentNullException>(securitySettings != null); - - IProtocolMessage response; - if (securitySettings.IsAssociationInPermittedRange(Protocol, this.AssociationType) && - HmacShaAssociation.IsDHSessionCompatible(Protocol, this.AssociationType, this.SessionType)) { - response = this.CreateResponseCore(); - - // Create and store the association if this is a successful response. - var successResponse = response as AssociateSuccessfulResponse; - if (successResponse != null) { - successResponse.CreateAssociation(this, associationStore, securitySettings); - } - } else { - response = this.CreateUnsuccessfulResponse(securitySettings); - } - - 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(); - - /// <summary> - /// Creates a response that notifies the Relying Party that the requested - /// association type is not supported by this Provider, and offers - /// an alternative association type, if possible. - /// </summary> - /// <param name="securitySettings">The security settings that apply to this Provider.</param> - /// <returns>The response to send to the Relying Party.</returns> - private AssociateUnsuccessfulResponse CreateUnsuccessfulResponse(ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(securitySettings != null); - - var unsuccessfulResponse = new AssociateUnsuccessfulResponse(this.Version, this); - - // The strategy here is to suggest that the RP try again with the lowest - // permissible security settings, giving the RP the best chance of being - // able to match with a compatible request. - bool unencryptedAllowed = this.Recipient.IsTransportSecure(); - bool useDiffieHellman = !unencryptedAllowed; - string associationType, sessionType; - if (HmacShaAssociation.TryFindBestAssociation(Protocol, false, securitySettings, useDiffieHellman, out associationType, out sessionType)) { - ErrorUtilities.VerifyInternal(this.AssociationType != associationType, "The RP asked for an association that should have been allowed, but the OP is trying to suggest the same one as an alternative!"); - unsuccessfulResponse.AssociationType = associationType; - unsuccessfulResponse.SessionType = sessionType; - Logger.OpenId.InfoFormat( - "Association requested of type '{0}' and session '{1}', which the Provider does not support. Sending back suggested alternative of '{0}' with session '{1}'.", - this.AssociationType, - this.SessionType, - unsuccessfulResponse.AssociationType, - unsuccessfulResponse.SessionType); - } else { - Logger.OpenId.InfoFormat("Association requested of type '{0}' and session '{1}', which the Provider does not support. No alternative association type qualified for suggesting back to the Relying Party.", this.AssociationType, this.SessionType); - } - - return unsuccessfulResponse; - } } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateSuccessfulResponse.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateSuccessfulResponse.cs index 42d8816..c3d8938 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateSuccessfulResponse.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateSuccessfulResponse.cs @@ -12,7 +12,6 @@ namespace DotNetOpenAuth.OpenId.Messages { using System.Linq; using System.Text; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.Provider; /// <summary> /// The base class that all successful association response messages derive from. @@ -24,11 +23,6 @@ namespace DotNetOpenAuth.OpenId.Messages { [ContractClass(typeof(AssociateSuccessfulResponseContract))] internal abstract class AssociateSuccessfulResponse : DirectResponseBase { /// <summary> - /// A flag indicating whether an association has already been created. - /// </summary> - private bool associationCreated; - - /// <summary> /// Initializes a new instance of the <see cref="AssociateSuccessfulResponse"/> class. /// </summary> /// <param name="responseVersion">The OpenID version of the response message.</param> @@ -94,66 +88,5 @@ namespace DotNetOpenAuth.OpenId.Messages { this.SessionType); } } - - /// <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> - /// <param name="associationStore">The Provider's association store.</param> - /// <param name="securitySettings">The security settings for the Provider. Should be <c>null</c> for Relying Parties.</param> - /// <returns> - /// The created association. - /// </returns> - /// <remarks> - /// The response message is updated to include the details of the created association by this method. - /// This method is called by both the Provider and the Relying Party, but actually performs - /// quite different operations in either scenario. - /// </remarks> - internal Association CreateAssociation(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(request != null); - 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 { - ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings"); - association = this.CreateAssociationAtProvider(request, associationStore, securitySettings); - 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> - /// <param name="associationStore">The Provider's association store.</param> - /// <param name="securitySettings">The security settings of the Provider.</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, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings); - - /// <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/OpenId/Messages/AssociateSuccessfulResponseContract.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateSuccessfulResponseContract.cs index d474608..39a79a4 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateSuccessfulResponseContract.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateSuccessfulResponseContract.cs @@ -8,23 +8,10 @@ namespace DotNetOpenAuth.OpenId.Messages { using System.Linq; using System.Text; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.Provider; [ContractClassFor(typeof(AssociateSuccessfulResponse))] internal abstract class AssociateSuccessfulResponseContract : AssociateSuccessfulResponse { protected AssociateSuccessfulResponseContract() : base(null, null) { } - - protected override Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(request != null); - Contract.Requires<ArgumentNullException>(associationStore != null); - Contract.Requires<ArgumentNullException>(securitySettings != null); - throw new NotImplementedException(); - } - - protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { - Contract.Requires<ArgumentNullException>(request != null); - throw new NotImplementedException(); - } } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateUnencryptedRequest.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateUnencryptedRequest.cs index ef302a5..b180ceb 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateUnencryptedRequest.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateUnencryptedRequest.cs @@ -60,7 +60,7 @@ namespace DotNetOpenAuth.OpenId.Messages { /// <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() { + protected /*override */IProtocolMessage CreateResponseCore() { var response = new AssociateUnencryptedResponse(this.Version, this); response.AssociationType = this.AssociationType; return response; diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateUnencryptedResponse.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateUnencryptedResponse.cs index 7e2194a..b7a0139 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateUnencryptedResponse.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/AssociateUnencryptedResponse.cs @@ -8,7 +8,6 @@ namespace DotNetOpenAuth.OpenId.Messages { using System; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Reflection; - using DotNetOpenAuth.OpenId.Provider; /// <summary> /// The successful unencrypted association response message. @@ -32,39 +31,5 @@ namespace DotNetOpenAuth.OpenId.Messages { /// </summary> [MessagePart("mac_key", IsRequired = true, AllowEmpty = false)] internal byte[] MacKey { 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> - /// <param name="associationStore">The Provider's association store.</param> - /// <param name="securitySettings">The security settings of the Provider.</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> - /// </remarks> - protected override Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { - Association association = HmacShaAssociation.Create(Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings); - 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/OpenId/Messages/CheckAuthenticationResponse.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/CheckAuthenticationResponse.cs index f4d5243..f52ccf8 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/CheckAuthenticationResponse.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/CheckAuthenticationResponse.cs @@ -12,7 +12,6 @@ namespace DotNetOpenAuth.OpenId.Messages { using System.Text; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.ChannelElements; - using DotNetOpenAuth.OpenId.Provider; /// <summary> /// The message sent from the Provider to the Relying Party to confirm/deny @@ -30,29 +29,6 @@ namespace DotNetOpenAuth.OpenId.Messages { } /// <summary> - /// Initializes a new instance of the <see cref="CheckAuthenticationResponse"/> class - /// for use by the Provider. - /// </summary> - /// <param name="request">The request that this message is responding to.</param> - /// <param name="provider">The OpenID Provider that is preparing to send this response.</param> - internal CheckAuthenticationResponse(CheckAuthenticationRequest request, OpenIdProvider provider) - : base(request.Version, request) { - Contract.Requires<ArgumentNullException>(provider != null); - - // The channel's binding elements have already set the request's IsValid property - // appropriately. We just copy it into the response message. - this.IsValid = request.IsValid; - - // Confirm the RP should invalidate the association handle only if the association - // is not valid (any longer). OpenID 2.0 section 11.4.2.2. - IndirectSignedResponse signedResponse = new IndirectSignedResponse(request, provider.Channel); - string invalidateHandle = ((ITamperResistantOpenIdMessage)signedResponse).InvalidateHandle; - if (!string.IsNullOrEmpty(invalidateHandle) && !provider.AssociationStore.IsValid(signedResponse, false, invalidateHandle)) { - this.InvalidateHandle = invalidateHandle; - } - } - - /// <summary> /// Gets or sets a value indicating whether the signature of the verification request is valid. /// </summary> [MessagePart("is_valid", IsRequired = true)] diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Messages/CheckIdRequest.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/CheckIdRequest.cs index 09c36a5..0667dcb 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/CheckIdRequest.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/CheckIdRequest.cs @@ -11,7 +11,6 @@ namespace DotNetOpenAuth.OpenId.Messages { using System.Linq; using System.Text; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// An authentication request from a Relying Party to a Provider. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Messages/NegativeAssertionResponse.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/NegativeAssertionResponse.cs index 52ff884..5b6cb05 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/NegativeAssertionResponse.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/NegativeAssertionResponse.cs @@ -11,7 +11,6 @@ namespace DotNetOpenAuth.OpenId.Messages { using System.Linq; using System.Text; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// The message OpenID Providers send back to Relying Parties to refuse diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Messages/SignedResponseRequest.cs b/src/DotNetOpenAuth.OpenId/OpenId/Messages/SignedResponseRequest.cs index 7eb5407..b1c9283 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Messages/SignedResponseRequest.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Messages/SignedResponseRequest.cs @@ -12,7 +12,6 @@ namespace DotNetOpenAuth.OpenId.Messages { using System.Linq; using System.Text; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// An indirect request from a Relying Party to a Provider where the response diff --git a/src/DotNetOpenAuth.OpenId/OpenId/NoDiscoveryIdentifier.cs b/src/DotNetOpenAuth.OpenId/OpenId/NoDiscoveryIdentifier.cs index 1a6e7e9..7dc2c0c 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/NoDiscoveryIdentifier.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/NoDiscoveryIdentifier.cs @@ -10,7 +10,6 @@ namespace DotNetOpenAuth.OpenId { using System.Diagnostics.Contracts; using System.Linq; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// Wraps an existing Identifier and prevents it from performing discovery. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/OpenIdUtilities.cs b/src/DotNetOpenAuth.OpenId/OpenId/OpenIdUtilities.cs index 68babd9..f6a65eb 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/OpenIdUtilities.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/OpenIdUtilities.cs @@ -18,8 +18,6 @@ namespace DotNetOpenAuth.OpenId { using DotNetOpenAuth.OpenId.ChannelElements; using DotNetOpenAuth.OpenId.Extensions; using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// A set of utilities especially useful to OpenID. @@ -170,26 +168,5 @@ namespace DotNetOpenAuth.OpenId { ErrorUtilities.VerifyOperation(aggregator != null, OpenIdStrings.UnsupportedChannelConfiguration); return aggregator.Factories; } - - /// <summary> - /// Determines whether the association with the specified handle is (still) valid. - /// </summary> - /// <param name="associationStore">The association store.</param> - /// <param name="containingMessage">The OpenID message that referenced this association handle.</param> - /// <param name="isPrivateAssociation">A value indicating whether a private association is expected.</param> - /// <param name="handle">The association handle.</param> - /// <returns> - /// <c>true</c> if the specified containing message is valid; otherwise, <c>false</c>. - /// </returns> - internal static bool IsValid(this IProviderAssociationStore associationStore, IProtocolMessage containingMessage, bool isPrivateAssociation, string handle) { - Contract.Requires<ArgumentNullException>(associationStore != null); - Contract.Requires<ArgumentNullException>(containingMessage != null); - Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(handle)); - try { - return associationStore.Deserialize(containingMessage, isPrivateAssociation, handle) != null; - } catch (ProtocolException) { - return false; - } - } } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/OpenIdXrdsHelper.cs b/src/DotNetOpenAuth.OpenId/OpenId/OpenIdXrdsHelper.cs index 00468ed..94f5574 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/OpenIdXrdsHelper.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/OpenIdXrdsHelper.cs @@ -1,21 +1,11 @@ -//----------------------------------------------------------------------- -// <copyright file="OpenIdXrdsHelper.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.OpenId { +namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; - using System.Diagnostics.Contracts; using System.Linq; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; + using System.Text; + using System.Diagnostics.Contracts; using DotNetOpenAuth.Xrds; - /// <summary> - /// Adds OpenID-specific extension methods to the XrdsDocument class. - /// </summary> internal static class OpenIdXrdsHelper { /// <summary> /// Finds the Relying Party return_to receiving endpoints. @@ -52,149 +42,6 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> - /// Creates the service endpoints described in this document, useful for requesting - /// authentication of one of the OpenID Providers that result from it. - /// </summary> - /// <param name="xrds">The XrdsDocument instance to use in this process.</param> - /// <param name="claimedIdentifier">The claimed identifier that was used to discover this XRDS document.</param> - /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> - /// <returns> - /// A sequence of OpenID Providers that can assert ownership of the <paramref name="claimedIdentifier"/>. - /// </returns> - internal static IEnumerable<IdentifierDiscoveryResult> CreateServiceEndpoints(this IEnumerable<XrdElement> xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) { - Contract.Requires<ArgumentNullException>(xrds != null); - Contract.Requires<ArgumentNullException>(claimedIdentifier != null); - Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null); - Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); - - var endpoints = new List<IdentifierDiscoveryResult>(); - endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier)); - endpoints.AddRange(xrds.GenerateClaimedIdentifierServiceEndpoints(claimedIdentifier, userSuppliedIdentifier)); - - Logger.Yadis.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count); - Logger.Yadis.Debug(endpoints.ToStringDeferred(true)); - return endpoints; - } - - /// <summary> - /// Creates the service endpoints described in this document, useful for requesting - /// authentication of one of the OpenID Providers that result from it. - /// </summary> - /// <param name="xrds">The XrdsDocument instance to use in this process.</param> - /// <param name="userSuppliedIdentifier">The user-supplied i-name that was used to discover this XRDS document.</param> - /// <returns>A sequence of OpenID Providers that can assert ownership of the canonical ID given in this document.</returns> - internal static IEnumerable<IdentifierDiscoveryResult> CreateServiceEndpoints(this IEnumerable<XrdElement> xrds, XriIdentifier userSuppliedIdentifier) { - Contract.Requires<ArgumentNullException>(xrds != null); - Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null); - Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); - - var endpoints = new List<IdentifierDiscoveryResult>(); - endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier)); - endpoints.AddRange(xrds.GenerateClaimedIdentifierServiceEndpoints(userSuppliedIdentifier)); - Logger.Yadis.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count); - Logger.Yadis.Debug(endpoints.ToStringDeferred(true)); - return endpoints; - } - - /// <summary> - /// Generates OpenID Providers that can authenticate using directed identity. - /// </summary> - /// <param name="xrds">The XrdsDocument instance to use in this process.</param> - /// <param name="opIdentifier">The OP Identifier entered (and resolved) by the user. Essentially the user-supplied identifier.</param> - /// <returns>A sequence of the providers that can offer directed identity services.</returns> - private static IEnumerable<IdentifierDiscoveryResult> GenerateOPIdentifierServiceEndpoints(this IEnumerable<XrdElement> xrds, Identifier opIdentifier) { - Contract.Requires<ArgumentNullException>(xrds != null); - Contract.Requires<ArgumentNullException>(opIdentifier != null); - Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); - return from service in xrds.FindOPIdentifierServices() - from uri in service.UriElements - let protocol = Protocol.FindBestVersion(p => p.OPIdentifierServiceTypeURI, service.TypeElementUris) - let providerDescription = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris) - select IdentifierDiscoveryResult.CreateForProviderIdentifier(opIdentifier, providerDescription, service.Priority, uri.Priority); - } - - /// <summary> - /// Generates the OpenID Providers that are capable of asserting ownership - /// of a particular URI claimed identifier. - /// </summary> - /// <param name="xrds">The XrdsDocument instance to use in this process.</param> - /// <param name="claimedIdentifier">The claimed identifier.</param> - /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> - /// <returns> - /// A sequence of the providers that can assert ownership of the given identifier. - /// </returns> - private static IEnumerable<IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this IEnumerable<XrdElement> xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) { - Contract.Requires<ArgumentNullException>(xrds != null); - Contract.Requires<ArgumentNullException>(claimedIdentifier != null); - Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); - - return from service in xrds.FindClaimedIdentifierServices() - from uri in service.UriElements - where uri.Uri != null - let providerEndpoint = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris) - select IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, providerEndpoint, service.Priority, uri.Priority); - } - - /// <summary> - /// Generates the OpenID Providers that are capable of asserting ownership - /// of a particular XRI claimed identifier. - /// </summary> - /// <param name="xrds">The XrdsDocument instance to use in this process.</param> - /// <param name="userSuppliedIdentifier">The i-name supplied by the user.</param> - /// <returns>A sequence of the providers that can assert ownership of the given identifier.</returns> - private static IEnumerable<IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this IEnumerable<XrdElement> xrds, XriIdentifier userSuppliedIdentifier) { - // Cannot use code contracts because this method uses yield return. - ////Contract.Requires<ArgumentNullException>(xrds != null); - ////Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); - ErrorUtilities.VerifyArgumentNotNull(xrds, "xrds"); - - foreach (var service in xrds.FindClaimedIdentifierServices()) { - foreach (var uri in service.UriElements) { - // spec section 7.3.2.3 on Claimed Id -> CanonicalID substitution - if (service.Xrd.CanonicalID == null) { - Logger.Yadis.WarnFormat(XrdsStrings.MissingCanonicalIDElement, userSuppliedIdentifier); - break; // skip on to next service - } - ErrorUtilities.VerifyProtocol(service.Xrd.IsCanonicalIdVerified, XrdsStrings.CIDVerificationFailed, userSuppliedIdentifier); - - // In the case of XRI names, the ClaimedId is actually the CanonicalID. - var claimedIdentifier = new XriIdentifier(service.Xrd.CanonicalID); - var providerEndpoint = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris); - yield return IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, providerEndpoint, service.Priority, uri.Priority); - } - } - } - - /// <summary> - /// Enumerates the XRDS service elements that describe OpenID Providers offering directed identity assertions. - /// </summary> - /// <param name="xrds">The XrdsDocument instance to use in this process.</param> - /// <returns>A sequence of service elements.</returns> - private static IEnumerable<ServiceElement> FindOPIdentifierServices(this IEnumerable<XrdElement> xrds) { - Contract.Requires<ArgumentNullException>(xrds != null); - Contract.Ensures(Contract.Result<IEnumerable<ServiceElement>>() != null); - - return from xrd in xrds - from service in xrd.OpenIdProviderIdentifierServices - select service; - } - - /// <summary> - /// Returns the OpenID-compatible services described by a given XRDS document, - /// in priority order. - /// </summary> - /// <param name="xrds">The XrdsDocument instance to use in this process.</param> - /// <returns>A sequence of the services offered.</returns> - private static IEnumerable<ServiceElement> FindClaimedIdentifierServices(this IEnumerable<XrdElement> xrds) { - Contract.Requires<ArgumentNullException>(xrds != null); - Contract.Ensures(Contract.Result<IEnumerable<ServiceElement>>() != null); - - return from xrd in xrds - from service in xrd.OpenIdClaimedIdentifierServices - select service; - } - - /// <summary> /// Enumerates the XRDS service elements that describe OpenID Relying Party return_to URLs /// that can receive authentication assertions. /// </summary> diff --git a/src/DotNetOpenAuth.OpenId/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth.OpenId/OpenId/UriIdentifier.cs index 3bbf343..3737135 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/UriIdentifier.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/UriIdentifier.cs @@ -17,7 +17,6 @@ namespace DotNetOpenAuth.OpenId { using System.Web.UI.HtmlControls; using System.Xml; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Xrds; using DotNetOpenAuth.Yadis; diff --git a/src/DotNetOpenAuth.OpenId/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth.OpenId/OpenId/XriIdentifier.cs index 729f603..b31d577 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/XriIdentifier.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/XriIdentifier.cs @@ -13,7 +13,6 @@ namespace DotNetOpenAuth.OpenId { using System.Xml; using DotNetOpenAuth.Configuration; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Xrds; using DotNetOpenAuth.Yadis; diff --git a/src/DotNetOpenAuth.OpenId/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.OpenId/Properties/AssemblyInfo.cs index 2fe391c..a043ec6 100644 --- a/src/DotNetOpenAuth.OpenId/Properties/AssemblyInfo.cs +++ b/src/DotNetOpenAuth.OpenId/Properties/AssemblyInfo.cs @@ -52,7 +52,11 @@ using System.Web.UI; [assembly: InternalsVisibleTo("DotNetOpenAuth.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] [assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.RelyingParty, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.Provider, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] #else [assembly: InternalsVisibleTo("DotNetOpenAuth.Test")] [assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.RelyingParty")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.Provider")] #endif diff --git a/src/DotNetOpenAuth.sln b/src/DotNetOpenAuth.sln index 4ee1d93..d526431 100644 --- a/src/DotNetOpenAuth.sln +++ b/src/DotNetOpenAuth.sln @@ -47,7 +47,7 @@ EndProject Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "DotNetOpenAuth.TestWeb", "DotNetOpenAuth.TestWeb\", "{47A84EF7-68C3-4D47-926A-9CCEA6518531}" ProjectSection(WebsiteProperties) = preProject TargetFrameworkMoniker = ".NETFramework,Version%3Dv3.5" - ProjectReferences = "{4376ECC9-C346-4A99-B13C-FA93C0FBD2C9}|DotNetOpenAuth.Test.dll;{408D10B8-34BA-4CBD-B7AA-FEB1907ABA4C}|DotNetOpenAuth.InfoCard.dll;{60426312-6AE5-4835-8667-37EDEA670222}|DotNetOpenAuth.Messaging.dll;{A288FCC8-6FCF-46DA-A45E-5F9281556361}|DotNetOpenAuth.OAuth.dll;{3896A32A-E876-4C23-B9B8-78E17D134CD3}|DotNetOpenAuth.OpenId.dll;{56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}|DotNetOpenAuth.OAuth2.dll;" + ProjectReferences = "{4376ECC9-C346-4A99-B13C-FA93C0FBD2C9}|DotNetOpenAuth.Test.dll;{408D10B8-34BA-4CBD-B7AA-FEB1907ABA4C}|DotNetOpenAuth.InfoCard.dll;{60426312-6AE5-4835-8667-37EDEA670222}|DotNetOpenAuth.Messaging.dll;{A288FCC8-6FCF-46DA-A45E-5F9281556361}|DotNetOpenAuth.OAuth.dll;{3896A32A-E876-4C23-B9B8-78E17D134CD3}|DotNetOpenAuth.OpenId.dll;{56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}|DotNetOpenAuth.OAuth2.dll;{26DC877F-5987-48DD-9DDB-E62F2DE0E150}|Org.Mentalis.Security.Cryptography.dll;{F4CD3C04-6037-4946-B7A5-34BFC96A75D2}|Mono.Math.dll;" Debug.AspNetCompiler.VirtualPath = "/DotNetOpenAuth.TestWeb" Debug.AspNetCompiler.PhysicalPath = "DotNetOpenAuth.TestWeb\" Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\DotNetOpenAuth.TestWeb\" @@ -159,6 +159,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.InfoCard", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.OAuth2", "DotNetOpenAuth.OAuth2\DotNetOpenAuth.OAuth2.csproj", "{56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.OpenId.Provider", "DotNetOpenAuth.OpenId.Provider\DotNetOpenAuth.OpenId.Provider.csproj", "{F8284738-3B5D-4733-A511-38C23F4A763F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.OpenId.RelyingParty", "DotNetOpenAuth.OpenId.RelyingParty\DotNetOpenAuth.OpenId.RelyingParty.csproj", "{F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Math", "Mono.Math\Mono.Math.csproj", "{F4CD3C04-6037-4946-B7A5-34BFC96A75D2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Org.Mentalis.Security.Cryptography", "Org.Mentalis.Security.Cryptography\Org.Mentalis.Security.Cryptography.csproj", "{26DC877F-5987-48DD-9DDB-E62F2DE0E150}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution CodeAnalysis|Any CPU = CodeAnalysis|Any CPU @@ -326,22 +334,22 @@ Global {60426312-6AE5-4835-8667-37EDEA670222}.Release|Any CPU.Build.0 = Release|Any CPU {60426312-6AE5-4835-8667-37EDEA670222}.ReleaseNoUI|Any CPU.ActiveCfg = ReleaseNoUI|Any CPU {60426312-6AE5-4835-8667-37EDEA670222}.ReleaseNoUI|Any CPU.Build.0 = ReleaseNoUI|Any CPU - {3896A32A-E876-4C23-B9B8-78E17D134CD3}.CodeAnalysis|Any CPU.ActiveCfg = CodeAnalysis|Any CPU - {3896A32A-E876-4C23-B9B8-78E17D134CD3}.CodeAnalysis|Any CPU.Build.0 = CodeAnalysis|Any CPU + {3896A32A-E876-4C23-B9B8-78E17D134CD3}.CodeAnalysis|Any CPU.ActiveCfg = Debug|Any CPU + {3896A32A-E876-4C23-B9B8-78E17D134CD3}.CodeAnalysis|Any CPU.Build.0 = Debug|Any CPU {3896A32A-E876-4C23-B9B8-78E17D134CD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3896A32A-E876-4C23-B9B8-78E17D134CD3}.Debug|Any CPU.Build.0 = Debug|Any CPU {3896A32A-E876-4C23-B9B8-78E17D134CD3}.Release|Any CPU.ActiveCfg = Release|Any CPU {3896A32A-E876-4C23-B9B8-78E17D134CD3}.Release|Any CPU.Build.0 = Release|Any CPU - {3896A32A-E876-4C23-B9B8-78E17D134CD3}.ReleaseNoUI|Any CPU.ActiveCfg = ReleaseNoUI|Any CPU - {3896A32A-E876-4C23-B9B8-78E17D134CD3}.ReleaseNoUI|Any CPU.Build.0 = ReleaseNoUI|Any CPU + {3896A32A-E876-4C23-B9B8-78E17D134CD3}.ReleaseNoUI|Any CPU.ActiveCfg = Release|Any CPU + {3896A32A-E876-4C23-B9B8-78E17D134CD3}.ReleaseNoUI|Any CPU.Build.0 = Release|Any CPU {A288FCC8-6FCF-46DA-A45E-5F9281556361}.CodeAnalysis|Any CPU.ActiveCfg = CodeAnalysis|Any CPU {A288FCC8-6FCF-46DA-A45E-5F9281556361}.CodeAnalysis|Any CPU.Build.0 = CodeAnalysis|Any CPU {A288FCC8-6FCF-46DA-A45E-5F9281556361}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A288FCC8-6FCF-46DA-A45E-5F9281556361}.Debug|Any CPU.Build.0 = Debug|Any CPU {A288FCC8-6FCF-46DA-A45E-5F9281556361}.Release|Any CPU.ActiveCfg = Release|Any CPU {A288FCC8-6FCF-46DA-A45E-5F9281556361}.Release|Any CPU.Build.0 = Release|Any CPU - {A288FCC8-6FCF-46DA-A45E-5F9281556361}.ReleaseNoUI|Any CPU.ActiveCfg = ReleaseNoUI|Any CPU - {A288FCC8-6FCF-46DA-A45E-5F9281556361}.ReleaseNoUI|Any CPU.Build.0 = ReleaseNoUI|Any CPU + {A288FCC8-6FCF-46DA-A45E-5F9281556361}.ReleaseNoUI|Any CPU.ActiveCfg = Release|Any CPU + {A288FCC8-6FCF-46DA-A45E-5F9281556361}.ReleaseNoUI|Any CPU.Build.0 = Release|Any CPU {408D10B8-34BA-4CBD-B7AA-FEB1907ABA4C}.CodeAnalysis|Any CPU.ActiveCfg = CodeAnalysis|Any CPU {408D10B8-34BA-4CBD-B7AA-FEB1907ABA4C}.CodeAnalysis|Any CPU.Build.0 = CodeAnalysis|Any CPU {408D10B8-34BA-4CBD-B7AA-FEB1907ABA4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -356,8 +364,40 @@ Global {56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}.Debug|Any CPU.Build.0 = Debug|Any CPU {56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}.Release|Any CPU.ActiveCfg = Release|Any CPU {56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}.Release|Any CPU.Build.0 = Release|Any CPU - {56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}.ReleaseNoUI|Any CPU.ActiveCfg = ReleaseNoUI|Any CPU - {56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}.ReleaseNoUI|Any CPU.Build.0 = ReleaseNoUI|Any CPU + {56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}.ReleaseNoUI|Any CPU.ActiveCfg = Release|Any CPU + {56459A6C-6BA2-4BAC-A9C0-27E3BD961FA6}.ReleaseNoUI|Any CPU.Build.0 = Release|Any CPU + {F8284738-3B5D-4733-A511-38C23F4A763F}.CodeAnalysis|Any CPU.ActiveCfg = Debug|Any CPU + {F8284738-3B5D-4733-A511-38C23F4A763F}.CodeAnalysis|Any CPU.Build.0 = Debug|Any CPU + {F8284738-3B5D-4733-A511-38C23F4A763F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8284738-3B5D-4733-A511-38C23F4A763F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8284738-3B5D-4733-A511-38C23F4A763F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8284738-3B5D-4733-A511-38C23F4A763F}.Release|Any CPU.Build.0 = Release|Any CPU + {F8284738-3B5D-4733-A511-38C23F4A763F}.ReleaseNoUI|Any CPU.ActiveCfg = Release|Any CPU + {F8284738-3B5D-4733-A511-38C23F4A763F}.ReleaseNoUI|Any CPU.Build.0 = Release|Any CPU + {F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}.CodeAnalysis|Any CPU.ActiveCfg = Debug|Any CPU + {F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}.CodeAnalysis|Any CPU.Build.0 = Debug|Any CPU + {F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}.Release|Any CPU.Build.0 = Release|Any CPU + {F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}.ReleaseNoUI|Any CPU.ActiveCfg = Release|Any CPU + {F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}.ReleaseNoUI|Any CPU.Build.0 = Release|Any CPU + {F4CD3C04-6037-4946-B7A5-34BFC96A75D2}.CodeAnalysis|Any CPU.ActiveCfg = CodeAnalysis|Any CPU + {F4CD3C04-6037-4946-B7A5-34BFC96A75D2}.CodeAnalysis|Any CPU.Build.0 = CodeAnalysis|Any CPU + {F4CD3C04-6037-4946-B7A5-34BFC96A75D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F4CD3C04-6037-4946-B7A5-34BFC96A75D2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4CD3C04-6037-4946-B7A5-34BFC96A75D2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F4CD3C04-6037-4946-B7A5-34BFC96A75D2}.Release|Any CPU.Build.0 = Release|Any CPU + {F4CD3C04-6037-4946-B7A5-34BFC96A75D2}.ReleaseNoUI|Any CPU.ActiveCfg = Release|Any CPU + {F4CD3C04-6037-4946-B7A5-34BFC96A75D2}.ReleaseNoUI|Any CPU.Build.0 = Release|Any CPU + {26DC877F-5987-48DD-9DDB-E62F2DE0E150}.CodeAnalysis|Any CPU.ActiveCfg = CodeAnalysis|Any CPU + {26DC877F-5987-48DD-9DDB-E62F2DE0E150}.CodeAnalysis|Any CPU.Build.0 = CodeAnalysis|Any CPU + {26DC877F-5987-48DD-9DDB-E62F2DE0E150}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26DC877F-5987-48DD-9DDB-E62F2DE0E150}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26DC877F-5987-48DD-9DDB-E62F2DE0E150}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26DC877F-5987-48DD-9DDB-E62F2DE0E150}.Release|Any CPU.Build.0 = Release|Any CPU + {26DC877F-5987-48DD-9DDB-E62F2DE0E150}.ReleaseNoUI|Any CPU.ActiveCfg = Release|Any CPU + {26DC877F-5987-48DD-9DDB-E62F2DE0E150}.ReleaseNoUI|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/BigInteger.cs b/src/Mono.Math/BigInteger.cs index 33df8df..33df8df 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/BigInteger.cs +++ b/src/Mono.Math/BigInteger.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/ConfidenceFactor.cs b/src/Mono.Math/ConfidenceFactor.cs index fd0747d..fd0747d 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/ConfidenceFactor.cs +++ b/src/Mono.Math/ConfidenceFactor.cs diff --git a/src/Mono.Math/Mono.Math.csproj b/src/Mono.Math/Mono.Math.csproj new file mode 100644 index 0000000..c0d66b6 --- /dev/null +++ b/src/Mono.Math/Mono.Math.csproj @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + </PropertyGroup> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.props" /> + <PropertyGroup> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{F4CD3C04-6037-4946-B7A5-34BFC96A75D2}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Mono.Math</RootNamespace> + <AssemblyName>Mono.Math</AssemblyName> + </PropertyGroup> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.Product.props" /> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + </PropertyGroup> + <ItemGroup> + <Compile Include="BigInteger.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="ConfidenceFactor.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="NextPrimeFinder.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="PrimalityTests.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="PrimeGeneratorBase.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="SequentialSearchPrimeGeneratorBase.cs"> + <SubType>Code</SubType> + </Compile> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" /> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " /> +</Project>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/NextPrimeFinder.cs b/src/Mono.Math/NextPrimeFinder.cs index 19433f2..19433f2 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/NextPrimeFinder.cs +++ b/src/Mono.Math/NextPrimeFinder.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/PrimalityTests.cs b/src/Mono.Math/PrimalityTests.cs index b2ddc74..b2ddc74 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/PrimalityTests.cs +++ b/src/Mono.Math/PrimalityTests.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/PrimeGeneratorBase.cs b/src/Mono.Math/PrimeGeneratorBase.cs index 12b6a69..12b6a69 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/PrimeGeneratorBase.cs +++ b/src/Mono.Math/PrimeGeneratorBase.cs diff --git a/src/Mono.Math/Properties/AssemblyInfo.cs b/src/Mono.Math/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cea21c0 --- /dev/null +++ b/src/Mono.Math/Properties/AssemblyInfo.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------- +// <copyright file="AssemblyInfo.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +// We DON'T put an AssemblyVersionAttribute in here because it is generated in the build. + +using System; +using System.Diagnostics.Contracts; +using System.Net; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Permissions; +using System.Web.UI; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Mono Math")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DotNetOpenAuth")] +[assembly: AssemblyCopyright("Copyright © 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: NeutralResourcesLanguage("en-US")] +[assembly: CLSCompliant(true)] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7d73990c-47c0-4256-9f20-a893add9e289")] + +[assembly: ContractVerification(true)] + +#if StrongNameSigned +// See comment at top of this file. We need this so that strong-naming doesn't +// keep this assembly from being useful to shared host (medium trust) web sites. +[assembly: AllowPartiallyTrustedCallers] + +[assembly: InternalsVisibleTo("Org.Mentalis.Security.Cryptography, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +#else +[assembly: InternalsVisibleTo("Org.Mentalis.Security.Cryptography")] +#endif diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/SequentialSearchPrimeGeneratorBase.cs b/src/Mono.Math/SequentialSearchPrimeGeneratorBase.cs index a017ee4..a017ee4 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/mono/SequentialSearchPrimeGeneratorBase.cs +++ b/src/Mono.Math/SequentialSearchPrimeGeneratorBase.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/DHKeyGeneration.cs b/src/Org.Mentalis.Security.Cryptography/DHKeyGeneration.cs index 6eca6a0..6eca6a0 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/DHKeyGeneration.cs +++ b/src/Org.Mentalis.Security.Cryptography/DHKeyGeneration.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/DHParameters.cs b/src/Org.Mentalis.Security.Cryptography/DHParameters.cs index 8105125..8105125 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/DHParameters.cs +++ b/src/Org.Mentalis.Security.Cryptography/DHParameters.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/DiffieHellman.cs b/src/Org.Mentalis.Security.Cryptography/DiffieHellman.cs index 5019f70..5019f70 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/DiffieHellman.cs +++ b/src/Org.Mentalis.Security.Cryptography/DiffieHellman.cs diff --git a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/DiffieHellmanManaged.cs b/src/Org.Mentalis.Security.Cryptography/DiffieHellmanManaged.cs index 6ac28df..6ac28df 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/DiffieHellman/DiffieHellmanManaged.cs +++ b/src/Org.Mentalis.Security.Cryptography/DiffieHellmanManaged.cs diff --git a/src/Org.Mentalis.Security.Cryptography/Org.Mentalis.Security.Cryptography.csproj b/src/Org.Mentalis.Security.Cryptography/Org.Mentalis.Security.Cryptography.csproj new file mode 100644 index 0000000..c2b1055 --- /dev/null +++ b/src/Org.Mentalis.Security.Cryptography/Org.Mentalis.Security.Cryptography.csproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + </PropertyGroup> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.props" /> + <PropertyGroup> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{26DC877F-5987-48DD-9DDB-E62F2DE0E150}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Org.Mentalis.Security.Cryptography</RootNamespace> + <AssemblyName>Org.Mentalis.Security.Cryptography</AssemblyName> + </PropertyGroup> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.Product.props" /> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + </PropertyGroup> + <ItemGroup> + <Compile Include="DHKeyGeneration.cs" /> + <Compile Include="DHParameters.cs" /> + <Compile Include="DiffieHellman.cs" /> + <Compile Include="DiffieHellmanManaged.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Mono.Math\Mono.Math.csproj"> + <Project>{F4CD3C04-6037-4946-B7A5-34BFC96A75D2}</Project> + <Name>Mono.Math</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" /> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " /> +</Project>
\ No newline at end of file diff --git a/src/Org.Mentalis.Security.Cryptography/Properties/AssemblyInfo.cs b/src/Org.Mentalis.Security.Cryptography/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..064d991 --- /dev/null +++ b/src/Org.Mentalis.Security.Cryptography/Properties/AssemblyInfo.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------- +// <copyright file="AssemblyInfo.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +// We DON'T put an AssemblyVersionAttribute in here because it is generated in the build. + +using System; +using System.Diagnostics.Contracts; +using System.Net; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Permissions; +using System.Web.UI; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Org.Mentalis.Security.Cryptography")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DotNetOpenAuth")] +[assembly: AssemblyCopyright("Copyright © 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: NeutralResourcesLanguage("en-US")] +[assembly: CLSCompliant(true)] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7d73990c-47c0-4256-9f20-a893add9e289")] + +[assembly: ContractVerification(true)] + +#if StrongNameSigned +// See comment at top of this file. We need this so that strong-naming doesn't +// keep this assembly from being useful to shared host (medium trust) web sites. +[assembly: AllowPartiallyTrustedCallers] + +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +#else +[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId")] +#endif diff --git a/tools/DotNetOpenAuth.Product.props b/tools/DotNetOpenAuth.Product.props index 02c6dab..5bab3eb 100644 --- a/tools/DotNetOpenAuth.Product.props +++ b/tools/DotNetOpenAuth.Product.props @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFile)</MSBuildAllProjects> <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode> </PropertyGroup> <PropertyGroup> - <ApplicationIcon>$(ProjectRoot)doc\logo\dnoa-icon-colour.ico</ApplicationIcon> <OutputType>Library</OutputType> <RootNamespace>DotNetOpenAuth</RootNamespace> <FileAlignment>512</FileAlignment> |