/// <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="requestMessage">The request message.</param> /// <param name="securitySettings">The security settings that apply to this Provider.</param> /// <returns> /// The response to send to the Relying Party. /// </returns> private static AssociateUnsuccessfulResponse CreateUnsuccessfulResponse(IAssociateRequestProvider requestMessage, ProviderSecuritySettings securitySettings) { Requires.NotNull(requestMessage, "requestMessage"); Requires.NotNull(securitySettings, "securitySettings"); var unsuccessfulResponse = new AssociateUnsuccessfulResponse(requestMessage.Version, (AssociateRequest)requestMessage); // 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 = requestMessage.Recipient.IsTransportSecure(); bool useDiffieHellman = !unencryptedAllowed; var request = (AssociateRequest)requestMessage; var protocol = requestMessage.GetProtocol(); string associationType, sessionType; if (HmacShaAssociation.TryFindBestAssociation(protocol, false, securitySettings, useDiffieHellman, out associationType, out sessionType)) { ErrorUtilities.VerifyInternal(request.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}'.", request.AssociationType, request.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.", request.AssociationType, request.SessionType); } return(unsuccessfulResponse); }
/// <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="requestMessage">The request message.</param> /// <param name="securitySettings">The security settings that apply to this Provider.</param> /// <returns> /// The response to send to the Relying Party. /// </returns> private static AssociateUnsuccessfulResponse CreateUnsuccessfulResponse(IAssociateRequestProvider requestMessage, ProviderSecuritySettings securitySettings) { Requires.NotNull(requestMessage, "requestMessage"); Requires.NotNull(securitySettings, "securitySettings"); var unsuccessfulResponse = new AssociateUnsuccessfulResponse(requestMessage.Version, (AssociateRequest)requestMessage); // 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 = requestMessage.Recipient.IsTransportSecure(); bool useDiffieHellman = !unencryptedAllowed; var request = (AssociateRequest)requestMessage; var protocol = requestMessage.GetProtocol(); string associationType, sessionType; if (HmacShaAssociation.TryFindBestAssociation(protocol, false, securitySettings, useDiffieHellman, out associationType, out sessionType)) { ErrorUtilities.VerifyInternal(request.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}'.", request.AssociationType, request.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.", request.AssociationType, request.SessionType); } return unsuccessfulResponse; }
public void RPOnlyRenegotiatesOnce() { Protocol protocol = Protocol.V20; OpenIdCoordinator coordinator = new OpenIdCoordinator( rp => { var association = rp.AssociationManager.GetOrCreateAssociation(new ProviderEndpointDescription(OPUri, protocol.Version)); Assert.IsNull(association, "The RP should quietly give up when the OP misbehaves."); }, op => { // Receive initial request. var request = op.Channel.ReadFromRequest<AssociateRequest>(); // Send a renegotiate response AssociateUnsuccessfulResponse renegotiateResponse = new AssociateUnsuccessfulResponse(request.Version, request); renegotiateResponse.AssociationType = protocol.Args.SignatureAlgorithm.HMAC_SHA1; renegotiateResponse.SessionType = protocol.Args.SessionType.DH_SHA1; op.Channel.Respond(renegotiateResponse); // Receive second-try request = op.Channel.ReadFromRequest<AssociateRequest>(); // Send ANOTHER renegotiate response, at which point the DNOI RP should give up. renegotiateResponse = new AssociateUnsuccessfulResponse(request.Version, request); renegotiateResponse.AssociationType = protocol.Args.SignatureAlgorithm.HMAC_SHA256; renegotiateResponse.SessionType = protocol.Args.SessionType.DH_SHA256; op.Channel.Respond(renegotiateResponse); }); coordinator.Run(); }
public void RPRejectsMismatchingAssociationAndSessionBitLengths() { Protocol protocol = Protocol.V20; OpenIdCoordinator coordinator = new OpenIdCoordinator( rp => { var association = rp.AssociationManager.GetOrCreateAssociation(new ProviderEndpointDescription(OPUri, protocol.Version)); Assert.IsNull(association, "The RP should quietly give up when the OP misbehaves."); }, op => { // Receive initial request. var request = op.Channel.ReadFromRequest<AssociateRequest>(); // Send a mismatched response AssociateUnsuccessfulResponse renegotiateResponse = new AssociateUnsuccessfulResponse(request.Version, request); renegotiateResponse.AssociationType = protocol.Args.SignatureAlgorithm.HMAC_SHA1; renegotiateResponse.SessionType = protocol.Args.SessionType.DH_SHA256; op.Channel.Respond(renegotiateResponse); }); coordinator.Run(); }
public void RPRejectsUnrecognizedAssociationType() { Protocol protocol = Protocol.V20; OpenIdCoordinator coordinator = new OpenIdCoordinator( rp => { var association = rp.AssociationManager.GetOrCreateAssociation(new ProviderEndpointDescription(OPUri, protocol.Version)); Assert.IsNull(association, "The RP should quietly give up when the OP misbehaves."); }, op => { // Receive initial request. var request = op.Channel.ReadFromRequest<AssociateRequest>(); // Send a response that suggests a foreign association type. AssociateUnsuccessfulResponse renegotiateResponse = new AssociateUnsuccessfulResponse(request.Version, request); renegotiateResponse.AssociationType = "HMAC-UNKNOWN"; renegotiateResponse.SessionType = "DH-UNKNOWN"; op.Channel.Respond(renegotiateResponse); }); coordinator.Run(); }
public async Task RPOnlyRenegotiatesOnce() { Protocol protocol = Protocol.V20; int opStep = 0; HandleProvider( async (op, req) => { switch (++opStep) { case 1: // Receive initial request. var request = await op.Channel.ReadFromRequestAsync<AssociateRequest>(req, CancellationToken.None); // Send a renegotiate response var renegotiateResponse = new AssociateUnsuccessfulResponse(request.Version, request); renegotiateResponse.AssociationType = protocol.Args.SignatureAlgorithm.HMAC_SHA1; renegotiateResponse.SessionType = protocol.Args.SessionType.DH_SHA1; return await op.Channel.PrepareResponseAsync(renegotiateResponse, CancellationToken.None); case 2: // Receive second-try request = await op.Channel.ReadFromRequestAsync<AssociateRequest>(req, CancellationToken.None); // Send ANOTHER renegotiate response, at which point the DNOI RP should give up. renegotiateResponse = new AssociateUnsuccessfulResponse(request.Version, request); renegotiateResponse.AssociationType = protocol.Args.SignatureAlgorithm.HMAC_SHA256; renegotiateResponse.SessionType = protocol.Args.SessionType.DH_SHA256; return await op.Channel.PrepareResponseAsync(renegotiateResponse, CancellationToken.None); default: throw Assumes.NotReachable(); } }); var rp = this.CreateRelyingParty(); var association = await rp.AssociationManager.GetOrCreateAssociationAsync(new ProviderEndpointDescription(OPUri, protocol.Version), CancellationToken.None); Assert.IsNull(association, "The RP should quietly give up when the OP misbehaves."); }
public async Task RPRejectsMismatchingAssociationAndSessionBitLengths() { Protocol protocol = Protocol.V20; this.HandleProvider( async (op, req) => { // Receive initial request. var request = await op.Channel.ReadFromRequestAsync<AssociateRequest>(req, CancellationToken.None); // Send a mismatched response AssociateUnsuccessfulResponse renegotiateResponse = new AssociateUnsuccessfulResponse(request.Version, request); renegotiateResponse.AssociationType = protocol.Args.SignatureAlgorithm.HMAC_SHA1; renegotiateResponse.SessionType = protocol.Args.SessionType.DH_SHA256; return await op.Channel.PrepareResponseAsync(renegotiateResponse); }); var rp = this.CreateRelyingParty(); var association = await rp.AssociationManager.GetOrCreateAssociationAsync(new ProviderEndpointDescription(OPUri, protocol.Version), CancellationToken.None); Assert.IsNull(association, "The RP should quietly give up when the OP misbehaves."); }
public async Task RPRejectsUnrecognizedAssociationType() { Protocol protocol = Protocol.V20; HandleProvider( async (op, req) => { // Receive initial request. var request = await op.Channel.ReadFromRequestAsync<AssociateRequest>(req, CancellationToken.None); // Send a response that suggests a foreign association type. var renegotiateResponse = new AssociateUnsuccessfulResponse(request.Version, request); renegotiateResponse.AssociationType = "HMAC-UNKNOWN"; renegotiateResponse.SessionType = "DH-UNKNOWN"; return await op.Channel.PrepareResponseAsync(renegotiateResponse); }); var rp = this.CreateRelyingParty(); var association = await rp.AssociationManager.GetOrCreateAssociationAsync(new ProviderEndpointDescription(OPUri, protocol.Version), CancellationToken.None); Assert.IsNull(association, "The RP should quietly give up when the OP misbehaves."); }
public override void SetUp() { base.SetUp(); var request = new AssociateUnencryptedRequest(Protocol.V20.Version, new Uri("http://host")); this.response = new AssociateUnsuccessfulResponse(request.Version, request); }
/// <summary> /// Analyzes an incoming request message payload to discover what kind of /// message is embedded in it and returns the type, or null if no match is found. /// </summary> /// <param name="request">The message that was sent as a request that resulted in the response.</param> /// <param name="fields">The name/value pairs that make up the message payload.</param> /// <returns> /// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can /// deserialize to. Null if the request isn't recognized as a valid protocol message. /// </returns> public IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) { DirectResponseBase message = null; // Discern the OpenID version of the message. Protocol protocol = Protocol.V11; string ns; if (fields.TryGetValue(Protocol.V20.openidnp.ns, out ns)) { ErrorUtilities.VerifyProtocol(string.Equals(ns, Protocol.OpenId2Namespace, StringComparison.Ordinal), MessagingStrings.UnexpectedMessagePartValue, Protocol.V20.openidnp.ns, ns); protocol = Protocol.V20; } // Handle error messages generally. if (fields.ContainsKey(protocol.openidnp.error)) { message = new DirectErrorResponse(protocol.Version, request); } var associateRequest = request as AssociateRequest; if (associateRequest != null) { if (protocol.Version.Major >= 2 && fields.ContainsKey(protocol.openidnp.error_code)) { // This is a special recognized error case that we create a special message for. message = new AssociateUnsuccessfulResponse(protocol.Version, associateRequest); } else if (message == null) { if (OpenIdUtilities.IsDiffieHellmanPresent) { var associateDiffieHellmanRequest = request as AssociateDiffieHellmanRequest; if (associateDiffieHellmanRequest != null) { message = new AssociateDiffieHellmanRelyingPartyResponse(protocol.Version, associateDiffieHellmanRequest); } } var associateUnencryptedRequest = request as AssociateUnencryptedRequest; if (associateUnencryptedRequest != null) { message = new AssociateUnencryptedResponseRelyingParty(protocol.Version, associateUnencryptedRequest); } } } var checkAuthenticationRequest = request as CheckAuthenticationRequest; if (checkAuthenticationRequest != null && message == null) { message = new CheckAuthenticationResponse(protocol.Version, checkAuthenticationRequest); } if (message != null) { message.SetAsIncoming(); } return message; }