public void Best() { Association a = HmacShaAssociation.Create( Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "h1", this.sha1Secret, TimeSpan.FromHours(1)); Association b = HmacShaAssociation.Create( Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "h2", this.sha1Secret, TimeSpan.FromHours(1)); this.assocs.Set(a); this.assocs.Set(b); // make b the best by making a older a.Issued -= TimeSpan.FromHours(1); Assert.AreSame(b, this.assocs.Best.FirstOrDefault()); // now make a the best b.Issued -= TimeSpan.FromHours(2); Assert.AreSame(a, this.assocs.Best.FirstOrDefault()); }
/// <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="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, ProviderSecuritySettings securitySettings) { Association association = HmacShaAssociation.Create(Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, securitySettings); this.MacKey = association.SecretKey; 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="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, ProviderSecuritySettings securitySettings) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); var diffieHellmanRequest = request as AssociateDiffieHellmanRequest; ErrorUtilities.VerifyArgument(diffieHellmanRequest != null, "request"); ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings"); 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, securitySettings); this.AssociationHandle = association.Handle; this.ExpiresIn = association.SecondsTillExpiration; // 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. 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); }
private double ParameterizedCheckIdTest(Protocol protocol, string assocType) { Association assoc = HmacShaAssociation.Create( protocol, assocType, AssociationRelyingPartyType.Smart, this.provider.SecuritySettings); this.provider.AssociationStore.StoreAssociation(AssociationRelyingPartyType.Smart, assoc); var checkidRequest = this.CreateCheckIdRequest(true); Stopwatch timer = new Stopwatch(); timer.Start(); int iterations; for (iterations = 0; timer.ElapsedMilliseconds < TestRunTime.TotalMilliseconds; iterations++) { var request = (IAuthenticationRequest)this.provider.GetRequest(checkidRequest); request.IsAuthenticated = true; var response = this.provider.PrepareResponse(request); Assert.IsInstanceOf <PositiveAssertionResponse>(response.OriginalMessage); } timer.Stop(); double executionsPerSecond = GetExecutionsPerSecond(iterations, timer); TestUtilities.TestLogger.InfoFormat("Responded to {0} checkid messages in {1}; or {2} authentications per second.", iterations, timer.Elapsed, executionsPerSecond); return(executionsPerSecond); }
/// <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) { Requires.NotNull(protocol, "protocol"); Requires.NotNullOrEmpty(associationType, "associationType"); Requires.NotNull(associationStore, "associationStore"); Requires.NotNull(securitySettings, "securitySettings"); int secretLength = HmacShaAssociation.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 = HmacShaAssociation.DumbSecretLifetime; } string handle = associationStore.Serialize(secret, DateTime.UtcNow + lifetime, associationUse == AssociationRelyingPartyType.Dumb); Assumes.True(protocol != null); // All the way up to the method call, the condition holds, yet we get a Requires failure next Assumes.True(secret != null); Assumes.True(!string.IsNullOrEmpty(associationType)); var result = HmacShaAssociation.Create(protocol, associationType, handle, secret, lifetime); return(result); }
public void Sign() { Association assoc1 = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "h1", this.sha1Secret, TimeSpan.FromMinutes(2)); Association assoc2 = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "h2", this.sha1Secret2, TimeSpan.FromMinutes(2)); var data = new byte[] { 0xdd, 0xcc }; // sign once and verify that it's sane byte[] signature1 = assoc1.Sign(data); Assert.That(signature1, Is.Not.Null); Assert.That(signature1.Length, Is.Not.EqualTo(0)); // sign again and make sure it's different byte[] signature2 = assoc2.Sign(data); Assert.That(signature2, Is.Not.Null); Assert.That(signature2.Length, Is.Not.EqualTo(0)); Assert.That(signature1, Is.Not.EqualTo(signature2)); // sign again with the same secret and make sure it's the same. Assert.That(assoc1.Sign(data), Is.EqualTo(signature1)); // now change the data and make sure signature changes data[1] = 0xee; Assert.That(assoc1.Sign(data), Is.Not.EqualTo(signature1)); }
public void Sign() { Association assoc1 = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "h1", this.sha1Secret, TimeSpan.FromMinutes(2)); Association assoc2 = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "h2", this.sha1Secret2, TimeSpan.FromMinutes(2)); var data = new byte[] { 0xdd, 0xcc }; // sign once and verify that it's sane byte[] signature1 = assoc1.Sign(data); Assert.IsNotNull(signature1); Assert.AreNotEqual(0, signature1.Length); // sign again and make sure it's different byte[] signature2 = assoc2.Sign(data); Assert.IsNotNull(signature2); Assert.AreNotEqual(0, signature2.Length); Assert.IsFalse(MessagingUtilities.AreEquivalent(signature1, signature2)); // sign again with the same secret and make sure it's the same. Assert.IsTrue(MessagingUtilities.AreEquivalent(signature1, assoc1.Sign(data))); // now change the data and make sure signature changes data[1] = 0xee; Assert.IsFalse(MessagingUtilities.AreEquivalent(signature1, assoc1.Sign(data))); }
public void SignSome() { Association assoc = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "h1", sha1Secret, TimeSpan.FromMinutes(2)); const string prefix = "q."; var dict = new Dictionary <string, string>(); dict.Add("q.a", "b"); dict.Add("q.c", "d"); dict.Add("q.e", "f"); var signKeys = new List <string> { "a", "c" }; // don't sign e byte[] sig1 = assoc.Sign(dict, signKeys, prefix); // change the unsigned value and verify that the sig doesn't change dict["q.e"] = "g"; Assert.IsTrue(Util.ArrayEquals(sig1, assoc.Sign(dict, signKeys, prefix))); // change a signed value and verify that the sig does change. dict["q.c"] = "D"; Assert.IsFalse(Util.ArrayEquals(sig1, assoc.Sign(dict, signKeys, prefix))); // change the ordering of signed fields and verify that the signature changes. dict["q.c"] = "d"; // put this back first. Assert.IsTrue(Util.ArrayEquals(sig1, assoc.Sign(dict, signKeys, prefix))); signKeys.Insert(0, signKeys[1]); signKeys.RemoveAt(2); Assert.IsFalse(Util.ArrayEquals(sig1, assoc.Sign(dict, signKeys, prefix))); }
public void CreateRequests() { var rp = this.CreateRelyingParty(); StoreAssociation(rp, OPUri, HmacShaAssociation.Create("somehandle", new byte[20], TimeSpan.FromDays(1))); Identifier id = Identifier.Parse(GetMockIdentifier(ProtocolVersion.V20)); var requests = rp.CreateRequests(id, RPRealmUri, RPUri); Assert.AreEqual(1, requests.Count()); }
public async Task CreateRequest() { var rp = this.CreateRelyingParty(); StoreAssociation(rp, OPUri, HmacShaAssociation.Create("somehandle", new byte[20], TimeSpan.FromDays(1))); Identifier id = Identifier.Parse(GetMockIdentifier(ProtocolVersion.V20)); var req = await rp.CreateRequestAsync(id, RPRealmUri, RPUri); Assert.IsNotNull(req); }
public void HandleLifecycle() { Association a = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "somehandle", sha1Secret, TimeSpan.FromDays(1)); assocs.Set(a); Assert.AreSame(a, assocs.Get(a.Handle)); Assert.IsTrue(assocs.Remove(a.Handle)); Assert.IsNull(assocs.Get(a.Handle)); Assert.IsFalse(assocs.Remove(a.Handle)); }
/// <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> public 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); }
public void Properties() { string handle = "somehandle"; TimeSpan lifetime = TimeSpan.FromMinutes(2); Association assoc = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, handle, this.sha1Secret, lifetime); Assert.IsFalse(assoc.IsExpired); Assert.That(assoc.Issued, Is.EqualTo(DateTime.UtcNow).Within(deltaDateTime)); Assert.That(assoc.Expires, Is.EqualTo(DateTime.UtcNow + lifetime).Within(deltaDateTime)); Assert.That(assoc.Handle, Is.EqualTo(handle)); Assert.That(assoc.SecondsTillExpiration, Is.EqualTo(lifetime.TotalSeconds).Within(deltaDateTime.TotalSeconds)); Assert.That(assoc.SecretKey, Is.EqualTo(this.sha1Secret)); Assert.That(assoc.Issued.Millisecond, Is.EqualTo(0), "No milliseconds because this can be cut off in conversions."); }
public void Properties() { string handle = "somehandle"; TimeSpan lifetime = TimeSpan.FromMinutes(2); Association assoc = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, handle, this.sha1Secret, lifetime); Assert.IsFalse(assoc.IsExpired); Assert.IsTrue(Math.Abs((DateTime.Now - assoc.Issued.ToLocalTime()).TotalSeconds) < deltaDateTime.TotalSeconds); Assert.IsTrue(Math.Abs((DateTime.Now.ToLocalTime() + lifetime - assoc.Expires.ToLocalTime()).TotalSeconds) < deltaDateTime.TotalSeconds); Assert.AreEqual(handle, assoc.Handle); Assert.IsTrue(Math.Abs(lifetime.TotalSeconds - assoc.SecondsTillExpiration) < deltaDateTime.TotalSeconds); Assert.IsTrue(MessagingUtilities.AreEquivalent(this.sha1Secret, assoc.SecretKey)); Assert.AreEqual(0, assoc.Issued.Millisecond, "No milliseconds because this can be cut off in conversions."); }
public virtual Association CreateAssociation(AssociationRelyingPartyType associationType, OpenIdProvider provider) { if (provider == null && associationType == AssociationRelyingPartyType.Smart) { throw new ArgumentNullException("provider", "For Smart associations, the provider must be given."); } string assoc_type; Protocol associationProtocol; if (associationType == AssociationRelyingPartyType.Dumb) { // We'll just use the best association available. associationProtocol = Protocol.Default; assoc_type = associationProtocol.Args.SignatureAlgorithm.Best; } else { associationProtocol = provider.Protocol; assoc_type = Util.GetRequiredArg(provider.Query, provider.Protocol.openid.assoc_type); Debug.Assert(Array.IndexOf(provider.Protocol.Args.SignatureAlgorithm.All, assoc_type) >= 0, "This should have been checked by our caller."); } int secretLength = HmacShaAssociation.GetSecretLength(associationProtocol, assoc_type); RNGCryptoServiceProvider generator = new RNGCryptoServiceProvider(); byte[] secret = new byte[secretLength]; byte[] uniq_bytes = new byte[4]; string uniq; string handle; HmacShaAssociation assoc; generator.GetBytes(secret); generator.GetBytes(uniq_bytes); uniq = Convert.ToBase64String(uniq_bytes); double seconds = DateTime.UtcNow.Subtract(Association.UnixEpoch).TotalSeconds; handle = "{{" + assoc_type + "}{" + seconds + "}{" + uniq + "}"; TimeSpan lifeSpan = associationType == AssociationRelyingPartyType.Dumb ? dumbSecretLifetime : smartAssociationLifetime; assoc = HmacShaAssociation.Create(secretLength, handle, secret, lifeSpan); store.StoreAssociation(associationType, assoc); return(assoc); }
/// <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 = this.opAssociations.GetAssociation(AssociationRelyingPartyType.Dumb, this.opSecuritySettings); if (association == null) { association = HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.HMAC_SHA256, AssociationRelyingPartyType.Dumb, this.opSecuritySettings); this.opAssociations.StoreAssociation(AssociationRelyingPartyType.Dumb, association); } return(association); }
void initializeAssociation() { string assoc_type = Util.GetRequiredArg(Args, Protocol.openidnp.assoc_type); if (Array.IndexOf(Protocol.Args.SignatureAlgorithm.All, assoc_type) >= 0) { byte[] secret; string session_type; if (!Args.TryGetValue(Protocol.openidnp.session_type, out session_type) || Protocol.Args.SessionType.NoEncryption.Equals(session_type, StringComparison.Ordinal)) { secret = getDecoded(Protocol.openidnp.mac_key); } else { try { byte[] dh_server_public = getDecoded(Protocol.openidnp.dh_server_public); byte[] enc_mac_key = getDecoded(Protocol.openidnp.enc_mac_key); secret = DiffieHellmanUtil.SHAHashXorSecret(DiffieHellmanUtil.Lookup(Protocol, session_type), DH, dh_server_public, enc_mac_key); } catch (ArgumentException ex) { throw new OpenIdException(string.Format(CultureInfo.CurrentCulture, Strings.InvalidOpenIdQueryParameterValue, Protocol.openid.session_type, session_type), ex); } } string assocHandle = Util.GetRequiredArg(Args, Protocol.openidnp.assoc_handle); TimeSpan expiresIn = new TimeSpan(0, 0, Convert.ToInt32(Util.GetRequiredArg(Args, Protocol.openidnp.expires_in), CultureInfo.InvariantCulture)); try { Association = HmacShaAssociation.Create(Protocol, assoc_type, assocHandle, secret, expiresIn); } catch (ArgumentException ex) { throw new OpenIdException(string.Format(CultureInfo.CurrentCulture, Strings.InvalidOpenIdQueryParameterValue, Protocol.openid.assoc_type, assoc_type), ex); } } else { throw new OpenIdException(string.Format(CultureInfo.CurrentCulture, Strings.InvalidOpenIdQueryParameterValue, Protocol.openid.assoc_type, assoc_type)); } }
public async Task CreateRequestsWithEndpointFilter() { var rp = this.CreateRelyingParty(); StoreAssociation(rp, OPUri, HmacShaAssociation.Create("somehandle", new byte[20], TimeSpan.FromDays(1))); Identifier id = Identifier.Parse(GetMockIdentifier(ProtocolVersion.V20)); rp.EndpointFilter = opendpoint => true; var requests = await rp.CreateRequestsAsync(id, RPRealmUri, RPUri); Assert.AreEqual(1, requests.Count()); rp.EndpointFilter = opendpoint => false; requests = await rp.CreateRequestsAsync(id, RPRealmUri, RPUri); Assert.AreEqual(0, requests.Count()); }
/// <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) { ProviderSecuritySettings securitySettings = new ProviderSecuritySettings(); Association association = HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart, 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.Send(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); op.AssociationStore.StoreAssociation(AssociationRelyingPartyType.Smart, association); 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.Send(response); }); coordinator.Run(); }
public void Sign() { Association assoc1 = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "h1", sha1Secret, TimeSpan.FromMinutes(2)); Association assoc2 = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, "h2", sha1Secret2, TimeSpan.FromMinutes(2)); var dict = new Dictionary <string, string>(); dict.Add("a", "b"); dict.Add("c", "d"); var keys = new List <string>(); keys.Add("a"); keys.Add("c"); // sign once and verify that it's sane byte[] signature1 = assoc1.Sign(dict, keys); Assert.IsNotNull(signature1); Assert.AreNotEqual(0, signature1.Length); // sign again and make sure it's different byte[] signature2 = assoc2.Sign(dict, keys); Assert.IsNotNull(signature2); Assert.AreNotEqual(0, signature2.Length); Assert.IsFalse(Util.ArrayEquals(signature1, signature2)); // sign again with the same secret and make sure it's the same. Assert.IsTrue(Util.ArrayEquals(signature1, assoc1.Sign(dict, keys))); // now add data and make sure signature changes dict.Add("g", "h"); keys.Add("g"); Assert.IsFalse(Util.ArrayEquals(signature1, assoc1.Sign(dict, keys))); // now change existing data. dict.Remove("g"); keys.Remove("g"); dict["c"] = "e"; Assert.IsFalse(Util.ArrayEquals(signature1, assoc1.Sign(dict, keys))); dict.Remove("c"); keys.Remove("c"); Assert.IsFalse(Util.ArrayEquals(signature1, assoc1.Sign(dict, keys))); }
/// <summary> /// Gets an association to use for signing new data. /// </summary> /// <returns> /// The association, which may have previously existed or /// may have been created as a result of this call. /// </returns> private Association GetAssociation() { Association privateAssociation = this.store.GetAssociation(SecretUri, this.securitySettings); 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); 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.", this.securitySettings.PrivateSecretMaximumAge, DotNetOpenAuthSection.Configuration.OpenId.MaxAuthenticationTime); } this.store.StoreAssociation(SecretUri, privateAssociation); } return(privateAssociation); }
public void SignaturesMatchKnownGood() { Protocol protocol = Protocol.V20; var settings = new ProviderSecuritySettings(); var store = new AssociationMemoryStore <AssociationRelyingPartyType>(); byte[] associationSecret = Convert.FromBase64String("rsSwv1zPWfjPRQU80hciu8FPDC+GONAMJQ/AvSo1a2M="); Association association = HmacShaAssociation.Create("mock", associationSecret, TimeSpan.FromDays(1)); store.StoreAssociation(AssociationRelyingPartyType.Smart, association); SigningBindingElement signer = new SigningBindingElement(store, settings); signer.Channel = new TestChannel(this.MessageDescriptions); IndirectSignedResponse message = new IndirectSignedResponse(protocol.Version, new Uri("http://rp")); ITamperResistantOpenIdMessage signedMessage = message; message.ProviderEndpoint = new Uri("http://provider"); signedMessage.UtcCreationDate = DateTime.Parse("1/1/2009"); signedMessage.AssociationHandle = association.Handle; Assert.IsNotNull(signer.ProcessOutgoingMessage(message)); Assert.AreEqual("o9+uN7qTaUS9v0otbHTuNAtbkpBm14+es9QnNo6IHD4=", signedMessage.Signature); }
/// <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); }
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."); ProviderSecuritySettings securitySettings = new ProviderSecuritySettings(); Association association = sharedAssociation ? HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart, 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.Send(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) { op.AssociationStore.StoreAssociation(AssociationRelyingPartyType.Smart, association); } 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.Send(response); if (positive && (statelessRP || !sharedAssociation)) { var checkauthRequest = op.Channel.ReadFromRequest<CheckAuthenticationRequest>(); var checkauthResponse = new CheckAuthenticationResponse(checkauthRequest.Version, checkauthRequest); checkauthResponse.IsValid = checkauthRequest.IsValid; op.Channel.Send(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.Send(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(); }