/// <summary> /// Creates the association at the provider side after the association request has been received. /// </summary> /// <param name="request">The association request.</param> /// <param name="associationStore">The OpenID Provider's association store or handle encoder.</param> /// <param name="securitySettings">The security settings of the Provider.</param> /// <returns> /// The newly created association. /// </returns> /// <remarks> /// The response message is updated to include the details of the created association by this method, /// but the resulting association is <i>not</i> added to the association store and must be done by the caller. /// </remarks> public Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { var diffieHellmanRequest = request as AssociateDiffieHellmanRequest; ErrorUtilities.VerifyInternal(diffieHellmanRequest != null, "Expected a DH request type."); this.SessionType = this.SessionType ?? request.SessionType; // Go ahead and create the association first, complete with its secret that we're about to share. Association association = HmacShaAssociationProvider.Create(this.Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings); // We now need to securely communicate the secret to the relying party using Diffie-Hellman. // We do this by performing a DH algorithm on the secret and setting a couple of properties // that will be transmitted to the Relying Party. The RP will perform an inverse operation // using its part of a DH secret in order to decrypt the shared secret we just invented // above when we created the association. using (DiffieHellman dh = new DiffieHellmanManaged( diffieHellmanRequest.DiffieHellmanModulus ?? AssociateDiffieHellmanRequest.DefaultMod, diffieHellmanRequest.DiffieHellmanGen ?? AssociateDiffieHellmanRequest.DefaultGen, AssociateDiffieHellmanRequest.DefaultX)) { HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(this.Protocol, this.SessionType); this.DiffieHellmanServerPublic = DiffieHellmanUtilities.EnsurePositive(dh.CreateKeyExchange()); this.EncodedMacKey = DiffieHellmanUtilities.SHAHashXorSecret(hasher, dh, diffieHellmanRequest.DiffieHellmanConsumerPublic, association.SecretKey); } return(association); }
/// <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); }