Exemple #1
0
        /// <summary>
        /// Simulates an extension request and response.
        /// </summary>
        /// <param name="protocol">The protocol to use in the roundtripping.</param>
        /// <param name="requests">The extensions to add to the request message.</param>
        /// <param name="responses">The extensions to add to the response message.</param>
        /// <remarks>
        /// This method relies on the extension objects' Equals methods to verify
        /// accurate transport.  The Equals methods should be verified by separate tests.
        /// </remarks>
        internal static void Roundtrip(
            Protocol protocol,
            IEnumerable <IOpenIdMessageExtension> requests,
            IEnumerable <IOpenIdMessageExtension> responses)
        {
            var         securitySettings = new ProviderSecuritySettings();
            var         cryptoKeyStore   = new MemoryCryptoKeyStore();
            var         associationStore = new ProviderAssociationHandleEncoder(cryptoKeyStore);
            Association association      = HmacShaAssociationProvider.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart, associationStore, securitySettings);
            var         coordinator      = new OpenIdCoordinator(
                rp => {
                RegisterExtension(rp.Channel, Mocks.MockOpenIdExtension.Factory);
                var requestBase = new CheckIdRequest(protocol.Version, OpenIdTestBase.OPUri, AuthenticationRequestMode.Immediate);
                OpenIdTestBase.StoreAssociation(rp, OpenIdTestBase.OPUri, association);
                requestBase.AssociationHandle = association.Handle;
                requestBase.ClaimedIdentifier = "http://claimedid";
                requestBase.LocalIdentifier   = "http://localid";
                requestBase.ReturnTo          = OpenIdTestBase.RPUri;

                foreach (IOpenIdMessageExtension extension in requests)
                {
                    requestBase.Extensions.Add(extension);
                }

                rp.Channel.Respond(requestBase);
                var response = rp.Channel.ReadFromRequest <PositiveAssertionResponse>();

                var receivedResponses = response.Extensions.Cast <IOpenIdMessageExtension>();
                CollectionAssert <IOpenIdMessageExtension> .AreEquivalentByEquality(responses.ToArray(), receivedResponses.ToArray());
            },
                op => {
                RegisterExtension(op.Channel, Mocks.MockOpenIdExtension.Factory);
                var key = cryptoKeyStore.GetCurrentKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, TimeSpan.FromSeconds(1));
                op.CryptoKeyStore.StoreKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, key.Key, key.Value);
                var request          = op.Channel.ReadFromRequest <CheckIdRequest>();
                var response         = new PositiveAssertionResponse(request);
                var receivedRequests = request.Extensions.Cast <IOpenIdMessageExtension>();
                CollectionAssert <IOpenIdMessageExtension> .AreEquivalentByEquality(requests.ToArray(), receivedRequests.ToArray());

                foreach (var extensionResponse in responses)
                {
                    response.Extensions.Add(extensionResponse);
                }

                op.Channel.Respond(response);
            });

            coordinator.Run();
        }
		public void ExtensionOnlyChannelLevel() {
			Protocol protocol = Protocol.V20;
			AuthenticationRequestMode mode = AuthenticationRequestMode.Setup;

			var coordinator = new OpenIdCoordinator(
				rp => {
					var request = new SignedResponseRequest(protocol.Version, OPUri, mode);
					rp.Channel.Respond(request);
				},
				op => {
					var request = op.Channel.ReadFromRequest<SignedResponseRequest>();
					Assert.IsNotInstanceOf<CheckIdRequest>(request);
				});
			coordinator.Run();
		}
Exemple #3
0
        public void BadRequestsGenerateValidErrorResponses()
        {
            var coordinator = new OpenIdCoordinator(
                rp => {
                var nonOpenIdMessage         = new Mocks.TestDirectedMessage();
                nonOpenIdMessage.Recipient   = OPUri;
                nonOpenIdMessage.HttpMethods = HttpDeliveryMethods.PostRequest;
                MessagingTestBase.GetStandardTestMessage(MessagingTestBase.FieldFill.AllRequired, nonOpenIdMessage);
                var response = rp.Channel.Request <DirectErrorResponse>(nonOpenIdMessage);
                Assert.IsNotNull(response.ErrorMessage);
                Assert.AreEqual(Protocol.Default.Version, response.Version);
            },
                AutoProvider);

            coordinator.Run();
        }
        public void BadRequestsGenerateValidErrorResponses()
        {
            var coordinator = new OpenIdCoordinator(
                rp => {
                    var nonOpenIdMessage = new Mocks.TestDirectedMessage();
                    nonOpenIdMessage.Recipient = OPUri;
                    nonOpenIdMessage.HttpMethods = HttpDeliveryMethods.PostRequest;
                    MessagingTestBase.GetStandardTestMessage(MessagingTestBase.FieldFill.AllRequired, nonOpenIdMessage);
                    var response = rp.Channel.Request<DirectErrorResponse>(nonOpenIdMessage);
                    Assert.IsNotNull(response.ErrorMessage);
                    Assert.AreEqual(Protocol.Default.Version, response.Version);
                },
                AutoProvider);

            coordinator.Run();
        }
		public void UnsolicitedAssertion() {
			this.MockResponder.RegisterMockRPDiscovery();
			OpenIdCoordinator coordinator = new OpenIdCoordinator(
				rp => {
					rp.Channel.WebRequestHandler = this.MockResponder.MockWebRequestHandler;
					IAuthenticationResponse response = rp.GetResponse();
					Assert.AreEqual(AuthenticationStatus.Authenticated, response.Status);
				},
				op => {
					op.Channel.WebRequestHandler = this.MockResponder.MockWebRequestHandler;
					Identifier id = GetMockIdentifier(ProtocolVersion.V20);
					op.SendUnsolicitedAssertion(OPUri, RPRealmUri, id, OPLocalIdentifiers[0]);
					AutoProvider(op); // handle check_auth
				});
			coordinator.Run();
		}
		/// <summary>
		/// Simulates an extension request and response.
		/// </summary>
		/// <param name="protocol">The protocol to use in the roundtripping.</param>
		/// <param name="requests">The extensions to add to the request message.</param>
		/// <param name="responses">The extensions to add to the response message.</param>
		/// <remarks>
		/// This method relies on the extension objects' Equals methods to verify
		/// accurate transport.  The Equals methods should be verified by separate tests.
		/// </remarks>
		internal static void Roundtrip(
			Protocol protocol,
			IEnumerable<IOpenIdMessageExtension> requests,
			IEnumerable<IOpenIdMessageExtension> responses) {
			var securitySettings = new ProviderSecuritySettings();
			var cryptoKeyStore = new MemoryCryptoKeyStore();
			var associationStore = new ProviderAssociationHandleEncoder(cryptoKeyStore);
			Association association = HmacShaAssociationProvider.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart, associationStore, securitySettings);
			var coordinator = new OpenIdCoordinator(
				rp => {
					RegisterExtension(rp.Channel, Mocks.MockOpenIdExtension.Factory);
					var requestBase = new CheckIdRequest(protocol.Version, OpenIdTestBase.OPUri, AuthenticationRequestMode.Immediate);
					OpenIdTestBase.StoreAssociation(rp, OpenIdTestBase.OPUri, association);
					requestBase.AssociationHandle = association.Handle;
					requestBase.ClaimedIdentifier = "http://claimedid";
					requestBase.LocalIdentifier = "http://localid";
					requestBase.ReturnTo = OpenIdTestBase.RPUri;

					foreach (IOpenIdMessageExtension extension in requests) {
						requestBase.Extensions.Add(extension);
					}

					rp.Channel.Respond(requestBase);
					var response = rp.Channel.ReadFromRequest<PositiveAssertionResponse>();

					var receivedResponses = response.Extensions.Cast<IOpenIdMessageExtension>();
					CollectionAssert<IOpenIdMessageExtension>.AreEquivalentByEquality(responses.ToArray(), receivedResponses.ToArray());
				},
				op => {
					RegisterExtension(op.Channel, Mocks.MockOpenIdExtension.Factory);
					var key = cryptoKeyStore.GetCurrentKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, TimeSpan.FromSeconds(1));
					op.CryptoKeyStore.StoreKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, key.Key, key.Value);
					var request = op.Channel.ReadFromRequest<CheckIdRequest>();
					var response = new PositiveAssertionResponse(request);
					var receivedRequests = request.Extensions.Cast<IOpenIdMessageExtension>();
					CollectionAssert<IOpenIdMessageExtension>.AreEquivalentByEquality(requests.ToArray(), receivedRequests.ToArray());

					foreach (var extensionResponse in responses) {
						response.Extensions.Add(extensionResponse);
					}

					op.Channel.Respond(response);
				});
			coordinator.Run();
		}
		public void AssociateDiffieHellmanOverHttps() {
			Protocol protocol = Protocol.V20;
			OpenIdCoordinator coordinator = new OpenIdCoordinator(
				rp => {
					// We have to formulate the associate request manually,
					// since the DNOI RP won't voluntarily use DH on HTTPS.
					AssociateDiffieHellmanRequest request = new AssociateDiffieHellmanRequest(protocol.Version, new Uri("https://Provider"));
					request.AssociationType = protocol.Args.SignatureAlgorithm.HMAC_SHA256;
					request.SessionType = protocol.Args.SessionType.DH_SHA256;
					request.InitializeRequest();
					var response = rp.Channel.Request<AssociateSuccessfulResponse>(request);
					Assert.IsNotNull(response);
					Assert.AreEqual(request.AssociationType, response.AssociationType);
					Assert.AreEqual(request.SessionType, response.SessionType);
				},
				AutoProvider);
			coordinator.Run();
		}
Exemple #8
0
        public void GetRequest()
        {
            var httpInfo = new HttpRequestInfo("GET", new Uri("http://someUri"));

            Assert.IsNull(this.provider.GetRequest(httpInfo), "An irrelevant request should return null.");
            var providerDescription = new ProviderEndpointDescription(OPUri, Protocol.Default.Version);

            // Test some non-empty request scenario.
            OpenIdCoordinator coordinator = new OpenIdCoordinator(
                rp => {
                rp.Channel.Request(AssociateRequestRelyingParty.Create(rp.SecuritySettings, providerDescription));
            },
                op => {
                IRequest request = op.GetRequest();
                Assert.IsInstanceOf <AutoResponsiveRequest>(request);
                op.Respond(request);
            });

            coordinator.Run();
        }
        public void AssertionWithEndpointFilter()
        {
            var coordinator = new OpenIdCoordinator(
                rp => {
                    // register with RP so that id discovery passes
                    rp.Channel.WebRequestHandler = this.MockResponder.MockWebRequestHandler;

                    // Rig it to always deny the incoming OP
                    rp.EndpointFilter = op => false;

                    // Receive the unsolicited assertion
                    var response = rp.GetResponse();
                    Assert.AreEqual(AuthenticationStatus.Failed, response.Status);
                },
                op => {
                    Identifier id = GetMockIdentifier(ProtocolVersion.V20);
                    op.SendUnsolicitedAssertion(OPUri, GetMockRealm(false), id, id);
                    AutoProvider(op);
                });
            coordinator.Run();
        }
		public void ExtensionOnlyFacadeLevel() {
			Protocol protocol = Protocol.V20;
			var coordinator = new OpenIdCoordinator(
				rp => {
					var request = rp.CreateRequest(GetMockIdentifier(protocol.ProtocolVersion), RPRealmUri, RPUri);

					request.IsExtensionOnly = true;
					rp.Channel.Respond(request.RedirectingResponse.OriginalMessage);
					IAuthenticationResponse response = rp.GetResponse();
					Assert.AreEqual(AuthenticationStatus.ExtensionsOnly, response.Status);
				},
				op => {
					var assocRequest = op.GetRequest();
					op.Respond(assocRequest);

					var request = (IAnonymousRequest)op.GetRequest();
					request.IsApproved = true;
					Assert.IsNotInstanceOf<CheckIdRequest>(request);
					op.Respond(request);
				});
			coordinator.Run();
		}
Exemple #11
0
        public void AssertionWithEndpointFilter()
        {
            var coordinator = new OpenIdCoordinator(
                rp => {
                // register with RP so that id discovery passes
                rp.Channel.WebRequestHandler = this.MockResponder.MockWebRequestHandler;

                // Rig it to always deny the incoming OP
                rp.EndpointFilter = op => false;

                // Receive the unsolicited assertion
                var response = rp.GetResponse();
                Assert.AreEqual(AuthenticationStatus.Failed, response.Status);
            },
                op => {
                Identifier id = GetMockIdentifier(ProtocolVersion.V20);
                op.SendUnsolicitedAssertion(OPUri, GetMockRealm(false), id, id);
                AutoProvider(op);
            });

            coordinator.Run();
        }
Exemple #12
0
        public void CreateRequestMessage()
        {
            OpenIdCoordinator coordinator = new OpenIdCoordinator(
                rp => {
                Identifier id = this.GetMockIdentifier(ProtocolVersion.V20);
                IAuthenticationRequest authRequest = rp.CreateRequest(id, this.realm, this.returnTo);

                // Add some callback arguments
                authRequest.AddCallbackArguments("a", "b");
                authRequest.AddCallbackArguments(new Dictionary <string, string> {
                    { "c", "d" }, { "e", "f" }
                });

                // Assembly an extension request.
                ClaimsRequest sregRequest = new ClaimsRequest();
                sregRequest.Nickname      = DemandLevel.Request;
                authRequest.AddExtension(sregRequest);

                // Construct the actual authentication request message.
                var authRequestAccessor = AuthenticationRequest_Accessor.AttachShadow(authRequest);
                var req = authRequestAccessor.CreateRequestMessage();
                Assert.IsNotNull(req);

                // Verify that callback arguments were included.
                NameValueCollection callbackArguments = HttpUtility.ParseQueryString(req.ReturnTo.Query);
                Assert.AreEqual("b", callbackArguments["a"]);
                Assert.AreEqual("d", callbackArguments["c"]);
                Assert.AreEqual("f", callbackArguments["e"]);

                // Verify that extensions were included.
                Assert.AreEqual(1, req.Extensions.Count);
                Assert.IsTrue(req.Extensions.Contains(sregRequest));
            },
                AutoProvider);

            coordinator.Run();
        }
Exemple #13
0
        public void ExtensionsAreIdentifiedAsSignedOrUnsigned()
        {
            Protocol          protocol    = Protocol.Default;
            OpenIdCoordinator coordinator = new OpenIdCoordinator(
                rp => {
                RegisterMockExtension(rp.Channel);
                var response = rp.Channel.ReadFromRequest <IndirectSignedResponse>();
                Assert.AreEqual(1, response.SignedExtensions.Count(), "Signed extension should have been received.");
                Assert.AreEqual(0, response.UnsignedExtensions.Count(), "No unsigned extension should be present.");
                response = rp.Channel.ReadFromRequest <IndirectSignedResponse>();
                Assert.AreEqual(0, response.SignedExtensions.Count(), "No signed extension should have been received.");
                Assert.AreEqual(1, response.UnsignedExtensions.Count(), "Unsigned extension should have been received.");
            },
                op => {
                RegisterMockExtension(op.Channel);
                op.Channel.Respond(CreateResponseWithExtensions(protocol));
                op.Respond(op.GetRequest());                         // check_auth
                op.SecuritySettings.SignOutgoingExtensions = false;
                op.Channel.Respond(CreateResponseWithExtensions(protocol));
                op.Respond(op.GetRequest());                         // check_auth
            });

            coordinator.Run();
        }
		public void AssociateRenegotiateBitLength() {
			Protocol protocol = Protocol.V20;

			// The strategy is to make a simple request of the RP to establish an association,
			// and to more carefully observe the Provider-side of things to make sure that both
			// the OP and RP are behaving as expected.
			OpenIdCoordinator coordinator = new OpenIdCoordinator(
				rp => {
					var opDescription = new ProviderEndpointDescription(OPUri, protocol.Version);
					Association association = rp.AssociationManager.GetOrCreateAssociation(opDescription);
					Assert.IsNotNull(association, "Association failed to be created.");
					Assert.AreEqual(protocol.Args.SignatureAlgorithm.HMAC_SHA1, association.GetAssociationType(protocol));
				},
				op => {
					op.SecuritySettings.MaximumHashBitLength = 160; // Force OP to reject HMAC-SHA256

					// Receive initial request for an HMAC-SHA256 association.
					AutoResponsiveRequest req = (AutoResponsiveRequest)op.GetRequest();
					AssociateRequest associateRequest = (AssociateRequest)req.RequestMessage;
					Assert.AreEqual(protocol.Args.SignatureAlgorithm.HMAC_SHA256, associateRequest.AssociationType);

					// Ensure that the response is a suggestion that the RP try again with HMAC-SHA1
					AssociateUnsuccessfulResponse renegotiateResponse = (AssociateUnsuccessfulResponse)req.ResponseMessageTestHook;
					Assert.AreEqual(protocol.Args.SignatureAlgorithm.HMAC_SHA1, renegotiateResponse.AssociationType);
					op.Respond(req);

					// Receive second attempt request for an HMAC-SHA1 association.
					req = (AutoResponsiveRequest)op.GetRequest();
					associateRequest = (AssociateRequest)req.RequestMessage;
					Assert.AreEqual(protocol.Args.SignatureAlgorithm.HMAC_SHA1, associateRequest.AssociationType);

					// Ensure that the response is a success response.
					AssociateSuccessfulResponse successResponse = (AssociateSuccessfulResponse)req.ResponseMessageTestHook;
					Assert.AreEqual(protocol.Args.SignatureAlgorithm.HMAC_SHA1, successResponse.AssociationType);
					op.Respond(req);
				});
			coordinator.Run();
		}
		/// <summary>
		/// Runs a parameterized association flow test.
		/// </summary>
		/// <param name="opDescription">
		/// The description of the Provider that the relying party uses to formulate the request.  
		/// The specific host is not used, but the scheme is significant.
		/// </param>
		/// <param name="expectedAssociationType">
		/// The value of the openid.assoc_type parameter expected,
		/// or null if a failure is anticipated.
		/// </param>
		private void ParameterizedAssociationTest(
			ProviderEndpointDescription opDescription,
			string expectedAssociationType) {
			Protocol protocol = Protocol.Lookup(Protocol.Lookup(opDescription.Version).ProtocolVersion);
			bool expectSuccess = expectedAssociationType != null;
			bool expectDiffieHellman = !opDescription.Uri.IsTransportSecure();
			Association rpAssociation = null, opAssociation;
			AssociateSuccessfulResponse associateSuccessfulResponse = null;
			AssociateUnsuccessfulResponse associateUnsuccessfulResponse = null;
			OpenIdCoordinator coordinator = new OpenIdCoordinator(
				rp => {
					rp.SecuritySettings = this.RelyingPartySecuritySettings;
					rpAssociation = rp.AssociationManager.GetOrCreateAssociation(opDescription);
				},
				op => {
					op.SecuritySettings = this.ProviderSecuritySettings;
					IRequest req = op.GetRequest();
					Assert.IsNotNull(req, "Expected incoming request but did not receive it.");
					Assert.IsTrue(req.IsResponseReady);
					op.Respond(req);
				});
			coordinator.IncomingMessageFilter = message => {
				Assert.AreSame(opDescription.Version, message.Version, "The message was recognized as version {0} but was expected to be {1}.", message.Version, Protocol.Lookup(opDescription.Version).ProtocolVersion);
				var associateSuccess = message as AssociateSuccessfulResponse;
				var associateFailed = message as AssociateUnsuccessfulResponse;
				if (associateSuccess != null) {
					associateSuccessfulResponse = associateSuccess;
				}
				if (associateFailed != null) {
					associateUnsuccessfulResponse = associateFailed;
				}
			};
			coordinator.OutgoingMessageFilter = message => {
				Assert.AreEqual(opDescription.Version, message.Version, "The message was for version {0} but was expected to be for {1}.", message.Version, opDescription.Version);
			};
			coordinator.Run();

			if (expectSuccess) {
				Assert.IsNotNull(rpAssociation);
				Association actual = coordinator.RelyingParty.AssociationManager.AssociationStoreTestHook.GetAssociation(opDescription.Uri, rpAssociation.Handle);
				Assert.AreEqual(rpAssociation, actual);
				opAssociation = coordinator.Provider.AssociationStore.Deserialize(new TestSignedDirectedMessage(), false, rpAssociation.Handle);
				Assert.IsNotNull(opAssociation, "The Provider could not decode the association handle.");

				Assert.AreEqual(opAssociation.Handle, rpAssociation.Handle);
				Assert.AreEqual(expectedAssociationType, rpAssociation.GetAssociationType(protocol));
				Assert.AreEqual(expectedAssociationType, opAssociation.GetAssociationType(protocol));
				Assert.IsTrue(Math.Abs(opAssociation.SecondsTillExpiration - rpAssociation.SecondsTillExpiration) < 60);
				Assert.IsTrue(MessagingUtilities.AreEquivalent(opAssociation.SecretKey, rpAssociation.SecretKey));

				if (expectDiffieHellman) {
					Assert.IsInstanceOf<AssociateDiffieHellmanResponse>(associateSuccessfulResponse);
					var diffieHellmanResponse = (AssociateDiffieHellmanResponse)associateSuccessfulResponse;
					Assert.IsFalse(MessagingUtilities.AreEquivalent(diffieHellmanResponse.EncodedMacKey, rpAssociation.SecretKey), "Key should have been encrypted.");
				} else {
					Assert.IsInstanceOf<AssociateUnencryptedResponse>(associateSuccessfulResponse);
					var unencryptedResponse = (AssociateUnencryptedResponse)associateSuccessfulResponse;
				}
			} else {
				Assert.IsNull(coordinator.RelyingParty.AssociationManager.AssociationStoreTestHook.GetAssociation(opDescription.Uri, new RelyingPartySecuritySettings()));
			}
		}
		public void AssociateRenegotiateLimitedByRPSecuritySettings() {
			Protocol protocol = Protocol.V20;
			OpenIdCoordinator coordinator = new OpenIdCoordinator(
				rp => {
					rp.SecuritySettings.MinimumHashBitLength = 256;
					var association = rp.AssociationManager.GetOrCreateAssociation(new ProviderEndpointDescription(OPUri, protocol.Version));
					Assert.IsNull(association, "No association should have been created when RP and OP could not agree on association strength.");
				},
				op => {
					op.SecuritySettings.MaximumHashBitLength = 160;
					AutoProvider(op);
				});
			coordinator.Run();
		}
		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 void OPRejectsHttpNoEncryptionAssociateRequests() {
			Protocol protocol = Protocol.V20;
			OpenIdCoordinator coordinator = new OpenIdCoordinator(
				rp => {
					// We have to formulate the associate request manually,
					// since the DNOI RP won't voluntarily suggest no encryption at all.
					var request = new AssociateUnencryptedRequestNoSslCheck(protocol.Version, OPUri);
					request.AssociationType = protocol.Args.SignatureAlgorithm.HMAC_SHA256;
					request.SessionType = protocol.Args.SessionType.NoEncryption;
					var response = rp.Channel.Request<DirectErrorResponse>(request);
					Assert.IsNotNull(response);
				},
				AutoProvider);
			coordinator.Run();
		}
        public void CreateRequestMessage()
        {
            OpenIdCoordinator coordinator = new OpenIdCoordinator(
                rp => {
                    Identifier id = this.GetMockIdentifier(ProtocolVersion.V20);
                    IAuthenticationRequest authRequest = rp.CreateRequest(id, this.realm, this.returnTo);

                    // Add some callback arguments
                    authRequest.AddCallbackArguments("a", "b");
                    authRequest.AddCallbackArguments(new Dictionary<string, string> { { "c", "d" }, { "e", "f" } });

                    // Assembly an extension request.
                    ClaimsRequest sregRequest = new ClaimsRequest();
                    sregRequest.Nickname = DemandLevel.Request;
                    authRequest.AddExtension(sregRequest);

                    // Construct the actual authentication request message.
                    var authRequestAccessor = AuthenticationRequest_Accessor.AttachShadow(authRequest);
                    var req = authRequestAccessor.CreateRequestMessage();
                    Assert.IsNotNull(req);

                    // Verify that callback arguments were included.
                    NameValueCollection callbackArguments = HttpUtility.ParseQueryString(req.ReturnTo.Query);
                    Assert.AreEqual("b", callbackArguments["a"]);
                    Assert.AreEqual("d", callbackArguments["c"]);
                    Assert.AreEqual("f", callbackArguments["e"]);

                    // Verify that extensions were included.
                    Assert.AreEqual(1, req.Extensions.Count);
                    Assert.IsTrue(req.Extensions.Contains(sregRequest));
                },
                AutoProvider);
            coordinator.Run();
        }
 public void ExtensionsAreIdentifiedAsSignedOrUnsigned()
 {
     Protocol protocol = Protocol.Default;
     OpenIdCoordinator coordinator = new OpenIdCoordinator(
         rp => {
             RegisterMockExtension(rp.Channel);
             var response = rp.Channel.ReadFromRequest<IndirectSignedResponse>();
             Assert.AreEqual(1, response.SignedExtensions.Count(), "Signed extension should have been received.");
             Assert.AreEqual(0, response.UnsignedExtensions.Count(), "No unsigned extension should be present.");
             response = rp.Channel.ReadFromRequest<IndirectSignedResponse>();
             Assert.AreEqual(0, response.SignedExtensions.Count(), "No signed extension should have been received.");
             Assert.AreEqual(1, response.UnsignedExtensions.Count(), "Unsigned extension should have been received.");
         },
         op => {
             RegisterMockExtension(op.Channel);
             op.Channel.Send(CreateResponseWithExtensions(protocol));
             op.SendResponse(op.GetRequest()); // check_auth
             op.SecuritySettings.SignOutgoingExtensions = false;
             op.Channel.Send(CreateResponseWithExtensions(protocol));
             op.SendResponse(op.GetRequest()); // check_auth
         });
     coordinator.Run();
 }
		public void GetRequest() {
			HttpRequestInfo httpInfo = new HttpRequestInfo();
			httpInfo.UrlBeforeRewriting = new Uri("http://someUri");
			Assert.IsNull(this.provider.GetRequest(httpInfo), "An irrelevant request should return null.");
			var providerDescription = new ProviderEndpointDescription(OpenIdTestBase.OPUri, Protocol.Default.Version);

			// Test some non-empty request scenario.
			OpenIdCoordinator coordinator = new OpenIdCoordinator(
				rp => {
					rp.Channel.Request(AssociateRequestRelyingParty.Create(rp.SecuritySettings, providerDescription));
				},
				op => {
					IRequest request = op.GetRequest();
					Assert.IsInstanceOf<AutoResponsiveRequest>(request);
					op.Respond(request);
				});
			coordinator.Run();
		}
		private void ParameterizedAuthenticationTest(Protocol protocol, bool statelessRP, bool sharedAssociation, bool positive, bool immediate, bool tamper) {
			Contract.Requires<ArgumentException>(!statelessRP || !sharedAssociation, "The RP cannot be stateless while sharing an association with the OP.");
			Contract.Requires<ArgumentException>(positive || !tamper, "Cannot tamper with a negative response.");
			var securitySettings = new ProviderSecuritySettings();
			var cryptoKeyStore = new MemoryCryptoKeyStore();
			var associationStore = new ProviderAssociationHandleEncoder(cryptoKeyStore);
			Association association = sharedAssociation ? HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart, associationStore, securitySettings) : null;
			var coordinator = new OpenIdCoordinator(
				rp => {
					var request = new CheckIdRequest(protocol.Version, OPUri, immediate ? AuthenticationRequestMode.Immediate : AuthenticationRequestMode.Setup);

					if (association != null) {
						StoreAssociation(rp, OPUri, association);
						request.AssociationHandle = association.Handle;
					}

					request.ClaimedIdentifier = "http://claimedid";
					request.LocalIdentifier = "http://localid";
					request.ReturnTo = RPUri;
					request.Realm = RPUri;
					rp.Channel.Respond(request);
					if (positive) {
						if (tamper) {
							try {
								rp.Channel.ReadFromRequest<PositiveAssertionResponse>();
								Assert.Fail("Expected exception {0} not thrown.", typeof(InvalidSignatureException).Name);
							} catch (InvalidSignatureException) {
								TestLogger.InfoFormat("Caught expected {0} exception after tampering with signed data.", typeof(InvalidSignatureException).Name);
							}
						} else {
							var response = rp.Channel.ReadFromRequest<PositiveAssertionResponse>();
							Assert.IsNotNull(response);
							Assert.AreEqual(request.ClaimedIdentifier, response.ClaimedIdentifier);
							Assert.AreEqual(request.LocalIdentifier, response.LocalIdentifier);
							Assert.AreEqual(request.ReturnTo, response.ReturnTo);

							// Attempt to replay the message and verify that it fails.
							// Because in various scenarios and protocol versions different components
							// notice the replay, we can get one of two exceptions thrown.
							// When the OP notices the replay we get a generic InvalidSignatureException.
							// When the RP notices the replay we get a specific ReplayMessageException.
							try {
								CoordinatingChannel channel = (CoordinatingChannel)rp.Channel;
								channel.Replay(response);
								Assert.Fail("Expected ProtocolException was not thrown.");
							} catch (ProtocolException ex) {
								Assert.IsTrue(ex is ReplayedMessageException || ex is InvalidSignatureException, "A {0} exception was thrown instead of the expected {1} or {2}.", ex.GetType(), typeof(ReplayedMessageException).Name, typeof(InvalidSignatureException).Name);
							}
						}
					} else {
						var response = rp.Channel.ReadFromRequest<NegativeAssertionResponse>();
						Assert.IsNotNull(response);
						if (immediate) {
							// Only 1.1 was required to include user_setup_url
							if (protocol.Version.Major < 2) {
								Assert.IsNotNull(response.UserSetupUrl);
							}
						} else {
							Assert.IsNull(response.UserSetupUrl);
						}
					}
				},
				op => {
					if (association != null) {
						var key = cryptoKeyStore.GetCurrentKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, TimeSpan.FromSeconds(1));
						op.CryptoKeyStore.StoreKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, key.Key, key.Value);
					}

					var request = op.Channel.ReadFromRequest<CheckIdRequest>();
					Assert.IsNotNull(request);
					IProtocolMessage response;
					if (positive) {
						response = new PositiveAssertionResponse(request);
					} else {
						response = new NegativeAssertionResponse(request, op.Channel);
					}
					op.Channel.Respond(response);

					if (positive && (statelessRP || !sharedAssociation)) {
						var checkauthRequest = op.Channel.ReadFromRequest<CheckAuthenticationRequest>();
						var checkauthResponse = new CheckAuthenticationResponse(checkauthRequest.Version, checkauthRequest);
						checkauthResponse.IsValid = checkauthRequest.IsValid;
						op.Channel.Respond(checkauthResponse);

						if (!tamper) {
							// Respond to the replay attack.
							checkauthRequest = op.Channel.ReadFromRequest<CheckAuthenticationRequest>();
							checkauthResponse = new CheckAuthenticationResponse(checkauthRequest.Version, checkauthRequest);
							checkauthResponse.IsValid = checkauthRequest.IsValid;
							op.Channel.Respond(checkauthResponse);
						}
					}
				});
			if (tamper) {
				coordinator.IncomingMessageFilter = message => {
					var assertion = message as PositiveAssertionResponse;
					if (assertion != null) {
						// Alter the Local Identifier between the Provider and the Relying Party.
						// If the signature binding element does its job, this should cause the RP
						// to throw.
						assertion.LocalIdentifier = "http://victim";
					}
				};
			}
			if (statelessRP) {
				coordinator.RelyingParty = new OpenIdRelyingParty(null);
			}

			coordinator.Run();
		}