/// <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); // 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; }
/// <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> protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { var diffieHellmanRequest = request as AssociateDiffieHellmanRequest; ErrorUtilities.VerifyArgument(diffieHellmanRequest != null, "request"); 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; }
/// <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="response">The response.</param> /// <param name="associationStore">The Provider's association store.</param> /// <param name="securitySettings">The security settings for the Provider. Should be <c>null</c> for Relying Parties.</param> /// <returns> /// The created association. /// </returns> /// <remarks> /// The response message is updated to include the details of the created association by this method. /// This method is called by both the Provider and the Relying Party, but actually performs /// quite different operations in either scenario. /// </remarks> internal static Association CreateAssociation(AssociateRequest request, IAssociateSuccessfulResponseProvider response, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { Requires.NotNull(request, "request"); Requires.NotNull(response, "response"); Requires.NotNull(securitySettings, "securitySettings"); // We need to initialize some common properties based on the created association. var association = response.CreateAssociationAtProvider(request, associationStore, securitySettings); response.ExpiresIn = association.SecondsTillExpiration; response.AssociationHandle = association.Handle; return association; }
public void ValidMessageTest() { this.request = new AssociateUnencryptedRequest(Protocol.V20.Version, this.secureRecipient); this.request.AssociationType = this.protocol.Args.SignatureAlgorithm.HMAC_SHA1; this.request.EnsureValidMessage(); }
public void Setup() { this.request = new AssociateUnencryptedRequest(this.protocol.Version, this.secureRecipient); }
/// <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="associationStore">The Provider's association store.</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> public Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { Association association = HmacShaAssociationProvider.Create(Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings); this.MacKey = association.SecretKey; return association; }
/// <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> Association IAssociateSuccessfulResponseRelyingParty.CreateAssociationAtRelyingParty(AssociateRequest request) { Requires.NotNull(request, "request"); throw new NotImplementedException(); }
/// <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> public Association CreateAssociationAtRelyingParty(AssociateRequest request) { Association association = HmacShaAssociation.Create(Protocol, this.AssociationType, this.AssociationHandle, this.MacKey, TimeSpan.FromSeconds(this.ExpiresIn)); return association; }
/// <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 abstract Association CreateAssociationAtRelyingParty(AssociateRequest request);
/// <summary> /// Creates a new association with a given Provider. /// </summary> /// <param name="provider">The provider to create an association with.</param> /// <param name="associateRequest">The associate request. May be <c>null</c>, which will always result in a <c>null</c> return value..</param> /// <param name="retriesRemaining">The number of times to try the associate request again if the Provider suggests it.</param> /// <returns> /// The newly created association, or null if no association can be created with /// the given Provider given the current security settings. /// </returns> private Association CreateNewAssociation(ProviderEndpointDescription provider, AssociateRequest associateRequest, int retriesRemaining) { ErrorUtilities.VerifyArgumentNotNull(provider, "provider"); if (associateRequest == null || retriesRemaining < 0) { // this can happen if security requirements and protocol conflict // to where there are no association types to choose from. return null; } try { var associateResponse = this.channel.Request(associateRequest); var associateSuccessfulResponse = associateResponse as AssociateSuccessfulResponse; var associateUnsuccessfulResponse = associateResponse as AssociateUnsuccessfulResponse; if (associateSuccessfulResponse != null) { Association association = associateSuccessfulResponse.CreateAssociation(associateRequest, null); this.associationStore.StoreAssociation(provider.Endpoint, association); return association; } else if (associateUnsuccessfulResponse != null) { if (string.IsNullOrEmpty(associateUnsuccessfulResponse.AssociationType)) { Logger.OpenId.Debug("Provider rejected an association request and gave no suggestion as to an alternative association type. Giving up."); return null; } if (!this.securitySettings.IsAssociationInPermittedRange(Protocol.Lookup(provider.ProtocolVersion), associateUnsuccessfulResponse.AssociationType)) { Logger.OpenId.DebugFormat("Provider rejected an association request and suggested '{0}' as an association to try, which this Relying Party does not support. Giving up.", associateUnsuccessfulResponse.AssociationType); return null; } if (retriesRemaining <= 0) { Logger.OpenId.Debug("Unable to agree on an association type with the Provider in the allowed number of retries. Giving up."); return null; } // Make sure the Provider isn't suggesting an incompatible pair of association/session types. Protocol protocol = Protocol.Lookup(provider.ProtocolVersion); ErrorUtilities.VerifyProtocol( HmacShaAssociation.IsDHSessionCompatible(protocol, associateUnsuccessfulResponse.AssociationType, associateUnsuccessfulResponse.SessionType), OpenIdStrings.IncompatibleAssociationAndSessionTypes, associateUnsuccessfulResponse.AssociationType, associateUnsuccessfulResponse.SessionType); associateRequest = AssociateRequest.Create(this.securitySettings, provider, associateUnsuccessfulResponse.AssociationType, associateUnsuccessfulResponse.SessionType); return this.CreateNewAssociation(provider, associateRequest, retriesRemaining - 1); } else { throw new ProtocolException(MessagingStrings.UnexpectedMessageReceivedOfMany); } } catch (ProtocolException ex) { // If the association failed because the remote server can't handle Expect: 100 Continue headers, // then our web request handler should have already accomodated for future calls. Go ahead and // immediately make one of those future calls now to try to get the association to succeed. if (StandardWebRequestHandler.IsExceptionFrom417ExpectationFailed(ex)) { return this.CreateNewAssociation(provider, associateRequest, retriesRemaining - 1); } // Since having associations with OPs is not totally critical, we'll log and eat // the exception so that auth may continue in dumb mode. Logger.OpenId.ErrorFormat("An error occurred while trying to create an association with {0}. {1}", provider.Endpoint, ex); return null; } }
protected override Association CreateAssociationAtProvider(AssociateRequest request, ProviderSecuritySettings securitySettings) { Contract.Requires<ArgumentNullException>(request != null); Contract.Requires<ArgumentNullException>(securitySettings != null); throw new NotImplementedException(); }
/// <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="ExpiresIn"/> and <see cref="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 abstract Association CreateAssociationAtProvider(AssociateRequest request, ProviderSecuritySettings securitySettings);
/// <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 for the Provider. Should be <c>null</c> for Relying Parties.</param> /// <returns>The created association.</returns> /// <remarks> /// <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> /// <para>This method is called by both the Provider and the Relying Party, but actually performs /// quite different operations in either scenario.</para> /// </remarks> internal Association CreateAssociation(AssociateRequest request, ProviderSecuritySettings securitySettings) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); ErrorUtilities.VerifyInternal(!this.associationCreated, "The association has already been created."); Association association; // If this message is outgoing, then we need to initialize some common // properties based on the created association. if (this.Incoming) { association = this.CreateAssociationAtRelyingParty(request); } else { ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings"); association = this.CreateAssociationAtProvider(request, securitySettings); this.ExpiresIn = association.SecondsTillExpiration; this.AssociationHandle = association.Handle; } this.associationCreated = true; return association; }
/// <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> /// Initializes a new instance of the <see cref="AssociateSuccessfulResponse"/> class. /// </summary> /// <param name="responseVersion">The OpenID version of the response message.</param> /// <param name="originatingRequest">The originating request.</param> internal AssociateSuccessfulResponse(Version responseVersion, AssociateRequest originatingRequest) : base(responseVersion, originatingRequest) { }
public void InvalidMessageTest() { this.request = new AssociateUnencryptedRequest(Protocol.V20.Version, this.insecureRecipient); this.request.AssociationType = this.protocol.Args.SignatureAlgorithm.HMAC_SHA1; this.request.EnsureValidMessage(); // no-encryption only allowed for secure channels. }
#pragma warning restore 0414 /// <summary> /// Initializes a new instance of the <see cref="AssociateUnsuccessfulResponse"/> class. /// </summary> /// <param name="responseVersion">The OpenID version of the response message.</param> /// <param name="originatingRequest">The originating request.</param> internal AssociateUnsuccessfulResponse(Version responseVersion, AssociateRequest originatingRequest) : base(responseVersion, originatingRequest) { this.ErrorMessage = string.Format(CultureInfo.CurrentCulture, OpenIdStrings.AssociationOrSessionTypeUnrecognizedOrNotSupported, originatingRequest.AssociationType, originatingRequest.SessionType); }
protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { Contract.Requires<ArgumentNullException>(request != null); throw new NotImplementedException(); }
/// <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="associationStore">The Provider's association store.</param> /// <param name="securitySettings">The security settings of the Provider.</param> /// <returns> /// The created association. /// </returns> Association IAssociateSuccessfulResponseProvider.CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { Requires.NotNull(request, "request"); Requires.NotNull(associationStore, "associationStore"); Requires.NotNull(securitySettings, "securitySettings"); throw new NotImplementedException(); }