diff options
Diffstat (limited to 'src')
17 files changed, 180 insertions, 153 deletions
diff --git a/src/DotNetOpenAuth.Test/AssemblyTesting.cs b/src/DotNetOpenAuth.Test/AssemblyTesting.cs index fecd97b..bfce6c6 100644 --- a/src/DotNetOpenAuth.Test/AssemblyTesting.cs +++ b/src/DotNetOpenAuth.Test/AssemblyTesting.cs @@ -14,8 +14,13 @@ namespace DotNetOpenAuth.Test { public static void AssemblyInitialize(TestContext tc) { // Make contract failures become test failures. Contract.ContractFailed += (sender, e) => { - e.Handled = true; - Assert.Fail(e.FailureKind.ToString() + ": " + e.DebugMessage); + if (e.FailureKind == ContractFailureKind.Precondition) { + // Currently we ignore these so that the regular ErrorUtilities can kick in. + e.Handled = true; + } else { + e.Handled = true; + Assert.Fail(e.FailureKind.ToString() + ": " + e.DebugMessage); + } }; } } diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index c9be4ef..1936bea 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -290,6 +290,7 @@ <Compile Include="OpenId\Extensions\SimpleRegistration\DemandLevel.cs" /> <Compile Include="OpenId\Extensions\SimpleRegistration\Gender.cs" /> <Compile Include="OpenId\Identifier.cs" /> + <Compile Include="OpenId\IdentifierContract.cs" /> <Compile Include="OpenId\Interop\AuthenticationResponseShim.cs" /> <Compile Include="OpenId\Interop\OpenIdRelyingPartyShim.cs" /> <Compile Include="OpenId\Messages\CheckAuthenticationRequest.cs" /> diff --git a/src/DotNetOpenAuth/Messaging/IMessage.cs b/src/DotNetOpenAuth/Messaging/IMessage.cs index 7eba540..031e908 100644 --- a/src/DotNetOpenAuth/Messaging/IMessage.cs +++ b/src/DotNetOpenAuth/Messaging/IMessage.cs @@ -47,6 +47,9 @@ namespace DotNetOpenAuth.Messaging { void EnsureValidMessage(); } + /// <summary> + /// Code contract for the <see cref="IMessage"/> interface. + /// </summary> [ContractClassFor(typeof(IMessage))] internal sealed class IMessageContract : IMessage { /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs index 77c4f6b..5c1f02a 100644 --- a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs +++ b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs @@ -31,6 +31,7 @@ namespace DotNetOpenAuth.Messaging { /// </summary> /// <param name="messageType">The specific <see cref="IMessage"/>-derived type /// that will be serialized and deserialized using this class.</param> + [ContractVerification(false)] // bugs/limitations in CC static analysis private MessageSerializer(Type messageType) { Contract.Requires(messageType != null); Contract.Requires(typeof(IMessage).IsAssignableFrom(messageType)); @@ -51,6 +52,7 @@ namespace DotNetOpenAuth.Messaging { /// </summary> /// <param name="messageType">The type of message that will be serialized/deserialized.</param> /// <returns>A message serializer for the given message type.</returns> + [ContractVerification(false)] // bugs/limitations in CC static analysis internal static MessageSerializer Get(Type messageType) { Contract.Requires(messageType != null); Contract.Requires(typeof(IMessage).IsAssignableFrom(messageType)); diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs index 1c3a37d..0e26860 100644 --- a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs +++ b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs @@ -56,6 +56,7 @@ namespace DotNetOpenAuth.Messaging.Reflection { /// <summary> /// Initializes static members of the <see cref="MessagePart"/> class. /// </summary> + [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "By design.")] [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Much more efficient initialization when we can call methods.")] static MessagePart() { Map<Uri>(uri => uri.AbsoluteUri, str => new Uri(str)); diff --git a/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs index c13fef5..28b7d6b 100644 --- a/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs +++ b/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs @@ -79,7 +79,7 @@ namespace DotNetOpenAuth.Messaging { ErrorUtilities.VerifyArgumentNotNull(request, "request"); ErrorUtilities.VerifySupported(this.CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name); - return GetRequestStreamCore(request, options); + return GetRequestStreamCore(request); } /// <summary> @@ -182,11 +182,10 @@ namespace DotNetOpenAuth.Messaging { /// Initiates a POST request and prepares for sending data. /// </summary> /// <param name="request">The HTTP request with information about the remote party to contact.</param> - /// <param name="options">The options to apply to this specific web request.</param> /// <returns> /// The stream where the POST entity can be written. /// </returns> - private static Stream GetRequestStreamCore(HttpWebRequest request, DirectWebRequestOptions options) { + private static Stream GetRequestStreamCore(HttpWebRequest request) { PrepareRequest(request, true); try { diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs index fcb862e..fa8e371 100644 --- a/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs +++ b/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs @@ -241,6 +241,47 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { } /// <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) { + ErrorUtilities.VerifyArgumentNotNull(response, "response"); + + // 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> @@ -294,7 +335,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { // instead of a shared one (if security settings indicate) // to protect the authenticating user from replay attacks. bool forcePrivateAssociation = this.opSecuritySettings.ProtectDownlevelReplayAttacks - && this.IsRelyingPartyVulnerableToReplays(null, (IndirectSignedResponse)signedMessage); + && IsRelyingPartyVulnerableToReplays(null, (IndirectSignedResponse)signedMessage); if (forcePrivateAssociation) { if (!string.IsNullOrEmpty(signedMessage.AssociationHandle)) { @@ -320,47 +361,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { } /// <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 bool IsRelyingPartyVulnerableToReplays(SignedResponseRequest request, IndirectSignedResponse response) { - ErrorUtilities.VerifyArgumentNotNull(response, "response"); - - // 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 a specific association referenced in a given message's association handle. /// </summary> /// <param name="signedMessage">The signed message whose association handle should be used to lookup the association to return.</param> diff --git a/src/DotNetOpenAuth/OpenId/Identifier.cs b/src/DotNetOpenAuth/OpenId/Identifier.cs index 8f3235b..c3f483f 100644 --- a/src/DotNetOpenAuth/OpenId/Identifier.cs +++ b/src/DotNetOpenAuth/OpenId/Identifier.cs @@ -218,61 +218,4 @@ namespace DotNetOpenAuth.OpenId { /// </returns> internal abstract bool TryRequireSsl(out Identifier secureIdentifier); } - - /// <summary> - /// Code Contract for the <see cref="Identifier"/> class. - /// </summary> - [ContractClassFor(typeof(Identifier))] - internal abstract class IdentifierContract : Identifier { - /// <summary> - /// Initializes a new instance of the <see cref="IdentifierContract"/> class. - /// </summary> - private IdentifierContract() - : base(false) { - } - - /// <summary> - /// Performs discovery on the Identifier. - /// </summary> - /// <param name="requestHandler">The web request handler to use for discovery.</param> - /// <returns> - /// An initialized structure containing the discovered provider endpoint information. - /// </returns> - internal override IEnumerable<ServiceEndpoint> Discover(IDirectWebRequestHandler requestHandler) { - Contract.Requires(requestHandler != null); - Contract.Ensures(Contract.Result<IEnumerable<ServiceEndpoint>>() != null); - throw new NotImplementedException(); - } - - /// <summary> - /// Returns an <see cref="Identifier"/> that has no URI fragment. - /// Quietly returns the original <see cref="Identifier"/> if it is not - /// a <see cref="UriIdentifier"/> or no fragment exists. - /// </summary> - /// <returns> - /// A new <see cref="Identifier"/> instance if there was a - /// fragment to remove, otherwise this same instance.. - /// </returns> - internal override Identifier TrimFragment() { - Contract.Ensures(Contract.Result<Identifier>() != null); - throw new NotImplementedException(); - } - - /// <summary> - /// Converts a given identifier to its secure equivalent. - /// UriIdentifiers originally created with an implied HTTP scheme change to HTTPS. - /// Discovery is made to require SSL for the entire resolution process. - /// </summary> - /// <param name="secureIdentifier">The newly created secure identifier. - /// If the conversion fails, <paramref name="secureIdentifier"/> retains - /// <i>this</i> identifiers identity, but will never discover any endpoints.</param> - /// <returns> - /// True if the secure conversion was successful. - /// False if the Identifier was originally created with an explicit HTTP scheme. - /// </returns> - internal override bool TryRequireSsl(out Identifier secureIdentifier) { - Contract.Ensures(Contract.ValueAtReturn(out secureIdentifier) != null); - throw new NotImplementedException(); - } - } } diff --git a/src/DotNetOpenAuth/OpenId/IdentifierContract.cs b/src/DotNetOpenAuth/OpenId/IdentifierContract.cs new file mode 100644 index 0000000..1758f06 --- /dev/null +++ b/src/DotNetOpenAuth/OpenId/IdentifierContract.cs @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------- +// <copyright file="IdentifierContract.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 DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.RelyingParty; + + /// <summary> + /// Code Contract for the <see cref="Identifier"/> class. + /// </summary> + [ContractClassFor(typeof(Identifier))] + internal abstract class IdentifierContract : Identifier { + /// <summary> + /// Prevents a default instance of the IdentifierContract class from being created. + /// </summary> + private IdentifierContract() + : base(false) { + } + + /// <summary> + /// Performs discovery on the Identifier. + /// </summary> + /// <param name="requestHandler">The web request handler to use for discovery.</param> + /// <returns> + /// An initialized structure containing the discovered provider endpoint information. + /// </returns> + internal override IEnumerable<ServiceEndpoint> Discover(IDirectWebRequestHandler requestHandler) { + Contract.Requires(requestHandler != null); + Contract.Ensures(Contract.Result<IEnumerable<ServiceEndpoint>>() != null); + throw new NotImplementedException(); + } + + /// <summary> + /// Returns an <see cref="Identifier"/> that has no URI fragment. + /// Quietly returns the original <see cref="Identifier"/> if it is not + /// a <see cref="UriIdentifier"/> or no fragment exists. + /// </summary> + /// <returns> + /// A new <see cref="Identifier"/> instance if there was a + /// fragment to remove, otherwise this same instance.. + /// </returns> + internal override Identifier TrimFragment() { + Contract.Ensures(Contract.Result<Identifier>() != null); + throw new NotImplementedException(); + } + + /// <summary> + /// Converts a given identifier to its secure equivalent. + /// UriIdentifiers originally created with an implied HTTP scheme change to HTTPS. + /// Discovery is made to require SSL for the entire resolution process. + /// </summary> + /// <param name="secureIdentifier">The newly created secure identifier. + /// If the conversion fails, <paramref name="secureIdentifier"/> retains + /// <i>this</i> identifiers identity, but will never discover any endpoints.</param> + /// <returns> + /// True if the secure conversion was successful. + /// False if the Identifier was originally created with an explicit HTTP scheme. + /// </returns> + internal override bool TryRequireSsl(out Identifier secureIdentifier) { + Contract.Ensures(Contract.ValueAtReturn(out secureIdentifier) != null); + throw new NotImplementedException(); + } + } +} diff --git a/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs b/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs index cbc8e7d..1d0629a 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs @@ -6,11 +6,11 @@ namespace DotNetOpenAuth.OpenId { using System.Collections.Generic; + using System.Diagnostics.Contracts; using System.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Xrds; - using System.Diagnostics.Contracts; /// <summary> /// Adds OpenID-specific extension methods to the XrdsDocument class. diff --git a/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs index 6c2c1c2..344c72f 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs @@ -26,10 +26,9 @@ namespace DotNetOpenAuth.OpenId.Provider { /// <summary> /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class. /// </summary> - /// <param name="provider">The provider that received the request message.</param> /// <param name="request">The request message.</param> /// <param name="response">The response that is ready for transmittal.</param> - internal AutoResponsiveRequest(OpenIdProvider provider, IDirectedProtocolMessage request, IProtocolMessage response) + internal AutoResponsiveRequest(IDirectedProtocolMessage request, IProtocolMessage response) : base(request) { ErrorUtilities.VerifyArgumentNotNull(response, "response"); @@ -40,9 +39,8 @@ namespace DotNetOpenAuth.OpenId.Provider { /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class /// for a response to an unrecognizable request. /// </summary> - /// <param name="provider">The provider that received the request message.</param> /// <param name="response">The response that is ready for transmittal.</param> - internal AutoResponsiveRequest(OpenIdProvider provider, IProtocolMessage response) + internal AutoResponsiveRequest(IProtocolMessage response) : base(IndirectResponseBase.GetVersion(response)) { ErrorUtilities.VerifyArgumentNotNull(response, "response"); diff --git a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs index 7742137..c28d613 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs @@ -178,12 +178,12 @@ namespace DotNetOpenAuth.OpenId.Provider { var checkAuthMessage = incomingMessage as CheckAuthenticationRequest; if (checkAuthMessage != null) { - return new AutoResponsiveRequest(this, incomingMessage, new CheckAuthenticationResponse(checkAuthMessage, this)); + return new AutoResponsiveRequest(incomingMessage, new CheckAuthenticationResponse(checkAuthMessage, this)); } var associateMessage = incomingMessage as AssociateRequest; if (associateMessage != null) { - return new AutoResponsiveRequest(this, incomingMessage, associateMessage.CreateResponse(this.AssociationStore, this.SecuritySettings)); + return new AutoResponsiveRequest(incomingMessage, associateMessage.CreateResponse(this.AssociationStore, this.SecuritySettings)); } throw ErrorUtilities.ThrowProtocol(MessagingStrings.UnexpectedMessageReceivedOfMany); @@ -363,9 +363,9 @@ namespace DotNetOpenAuth.OpenId.Provider { } if (incomingMessage != null) { - return new AutoResponsiveRequest(this, incomingMessage, errorMessage); + return new AutoResponsiveRequest(incomingMessage, errorMessage); } else { - return new AutoResponsiveRequest(this, errorMessage); + return new AutoResponsiveRequest(errorMessage); } } } diff --git a/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs index e5d0d74..a9e8030 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs @@ -23,7 +23,7 @@ namespace DotNetOpenAuth.OpenId.Provider { /// </summary> [DefaultEvent("AuthenticationChallenge")] [ToolboxData("<{0}:ProviderEndpoint runat='server' />")] - public class ProviderEndpoint : Control, IDisposable { + public class ProviderEndpoint : Control { /// <summary> /// The key used to store the pending authentication request in the ASP.NET session. /// </summary> diff --git a/src/DotNetOpenAuth/OpenId/Realm.cs b/src/DotNetOpenAuth/OpenId/Realm.cs index dbbfd43..c74009d 100644 --- a/src/DotNetOpenAuth/OpenId/Realm.cs +++ b/src/DotNetOpenAuth/OpenId/Realm.cs @@ -62,7 +62,7 @@ namespace DotNetOpenAuth.OpenId { /// <param name="realmUrl">The realm URL to use in the new instance.</param> [SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads", Justification = "Not all realms are valid URLs (because of wildcards).")] public Realm(string realmUrl) { - ErrorUtilities.VerifyNonZeroLength(realmUrl, "realmUrl"); + ErrorUtilities.VerifyArgumentNotNull(realmUrl, "realmUrl"); // not non-zero check so we throw UriFormatException later this.DomainWildcard = Regex.IsMatch(realmUrl, WildcardDetectionPattern); this.uri = new Uri(Regex.Replace(realmUrl, WildcardDetectionPattern, m => m.Groups[1].Value)); if (!this.uri.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase) && @@ -379,15 +379,6 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> - /// Verifies conditions that should be true for any valid state of this object. - /// </summary> - [ContractInvariantMethod] - private void ObjectInvariant() { - Contract.Invariant(this.uri != null); - Contract.Invariant(this.uri.AbsoluteUri != null); - } - - /// <summary> /// Calls <see cref="UriBuilder.ToString"/> if the argument is non-null. /// Otherwise throws <see cref="ArgumentNullException"/>. /// </summary> @@ -407,5 +398,15 @@ namespace DotNetOpenAuth.OpenId { // is safe: http://blog.nerdbank.net/2008/04/uriabsoluteuri-and-uritostring-are-not.html return realmUriBuilder.ToString(); } + + /// <summary> + /// Verifies conditions that should be true for any valid state of this object. + /// </summary> + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")] + [ContractInvariantMethod] + private void ObjectInvariant() { + Contract.Invariant(this.uri != null); + Contract.Invariant(this.uri.AbsoluteUri != null); + } } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/PrivateSecretManager.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/PrivateSecretManager.cs index 2fad181..09eea16 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/PrivateSecretManager.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/PrivateSecretManager.cs @@ -83,6 +83,16 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } /// <summary> + /// Creates the new association handle. + /// </summary> + /// <returns>The ASCII-encoded handle name.</returns> + private static string CreateNewAssociationHandle() { + string uniq = MessagingUtilities.GetCryptoRandomDataAsBase64(4); + string handle = "{" + DateTime.UtcNow.Ticks + "}{" + uniq + "}"; + return handle; + } + + /// <summary> /// Gets an association to use for signing new data. /// </summary> /// <returns> @@ -94,7 +104,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { if (privateAssociation == null || !privateAssociation.HasUsefulLifeRemaining) { int secretLength = HmacShaAssociation.GetSecretLength(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.Best); byte[] secret = MessagingUtilities.GetCryptoRandomData(secretLength); - privateAssociation = HmacShaAssociation.Create(this.CreateNewAssociationHandle(), secret, this.securitySettings.PrivateSecretMaximumAge); + privateAssociation = HmacShaAssociation.Create(CreateNewAssociationHandle(), secret, this.securitySettings.PrivateSecretMaximumAge); if (!privateAssociation.HasUsefulLifeRemaining) { Logger.WarnFormat( "Brand new private association has a shorter lifespan ({0}) than the maximum allowed authentication time for a user ({1}). This may lead to login failures.", @@ -107,15 +117,5 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { return privateAssociation; } - - /// <summary> - /// Creates the new association handle. - /// </summary> - /// <returns>The ASCII-encoded handle name.</returns> - private string CreateNewAssociationHandle() { - string uniq = MessagingUtilities.GetCryptoRandomDataAsBase64(4); - string handle = "{" + DateTime.UtcNow.Ticks + "}{" + uniq + "}"; - return handle; - } } } diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs index 41d5831..da0e4bb 100644 --- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs @@ -309,15 +309,6 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> - /// Verifies conditions that should be true for any valid state of this object. - /// </summary> - [ContractInvariantMethod] - private void ObjectInvariant() { - Contract.Invariant(this.Uri != null); - Contract.Invariant(this.Uri.AbsoluteUri != null); - } - - /// <summary> /// Searches HTML for the HEAD META tags that describe OpenID provider services. /// </summary> /// <param name="claimedIdentifier">The final URL that provided this HTML document. @@ -457,5 +448,15 @@ namespace DotNetOpenAuth.OpenId { canonicalUri = uriBuilder.Uri; return true; } + + /// <summary> + /// Verifies conditions that should be true for any valid state of this object. + /// </summary> + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")] + [ContractInvariantMethod] + private void ObjectInvariant() { + Contract.Invariant(this.Uri != null); + Contract.Invariant(this.Uri.AbsoluteUri != null); + } } } diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs index a978ae9..95e7bf0 100644 --- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Globalization; using System.Xml; @@ -217,21 +218,13 @@ namespace DotNetOpenAuth.OpenId { /// True if the secure conversion was successful. /// False if the Identifier was originally created with an explicit HTTP scheme. /// </returns> + [ContractVerification(false)] // bugs/limitations in CC static analysis internal override bool TryRequireSsl(out Identifier secureIdentifier) { secureIdentifier = IsDiscoverySecureEndToEnd ? this : new XriIdentifier(this, true); return true; } /// <summary> - /// Verifies conditions that should be true for any valid state of this object. - /// </summary> - [ContractInvariantMethod] - private void ObjectInvariant() { - Contract.Invariant(this.xriResolverProxy != null); - Contract.Invariant(this.canonicalXri != null); - } - - /// <summary> /// Takes any valid form of XRI string and returns the canonical form of the same XRI. /// </summary> /// <param name="xri">The xri to canonicalize.</param> @@ -263,5 +256,15 @@ namespace DotNetOpenAuth.OpenId { ErrorUtilities.VerifyProtocol(doc.IsXrdResolutionSuccessful, OpenIdStrings.XriResolutionFailed); return doc; } + + /// <summary> + /// Verifies conditions that should be true for any valid state of this object. + /// </summary> + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")] + [ContractInvariantMethod] + private void ObjectInvariant() { + Contract.Invariant(this.xriResolverProxy != null); + Contract.Invariant(this.canonicalXri != null); + } } } |