# File lib/openid/consumer.rb, line 514
    def do_id_res(nonce, consumer_id, server_id, server_url, query)
      user_setup_url = query["openid.user_setup_url"]
      if user_setup_url
        return SetupNeededResponse.new(user_setup_url)
      end
      
      return_to = query["openid.return_to"]
      server_id2 = query["openid.identity"]
      assoc_handle = query["openid.assoc_handle"]
      
      if return_to.nil?
        return FailureResponse.new(consumer_id, msg='openid.return_to was nil')
      elsif server_id2.nil?
        return FailureResponse.new(consumer_id, msg='openid.identity was nil')
      elsif assoc_handle.nil?
        return FailureResponse.new(consumer_id, msg='openid.assoc_handle was nil')
      end
      
      if server_id != server_id2
        return FailureResponse.new(consumer_id, msg='server ids do not match')
      end
      
      assoc = @store.get_association(server_url, assoc_handle)
    
      if assoc.nil?
        # It's not an association we know about. Dumb mode is our
        # only possible path for recovery.
        code, msg = self.check_auth(nonce, query, server_url)
        if code == SUCCESS
          return SuccessResponse.new(consumer_id, query)
        else
          return FailureResponse.new(consumer_id, "check_auth failed: #{msg}")
        end
      end

      if assoc.expires_in <= 0
        OpenID::Util.log("Association with #{server_url} expired")
        return FailureResponse.new(consumer_id, 'assoc expired')
      end

      # Check the signature
      sig = query["openid.sig"]
      return FailureResponse.new(consumer_id, 'no sig') if sig.nil?
      signed = query["openid.signed"]
      return FailureResponse.new(consumer_id, 'no signed') if signed.nil?
      
      args = OpenID::Util.get_openid_params(query)
      signed_list = signed.split(",")
      _signed, v_sig = OpenID::Util.sign_reply(args, assoc.secret, signed_list)

      if v_sig != sig
        return FailureResponse.new(consumer_id, 'sig mismatch')
      end

      unless @store.use_nonce(nonce)
        return FailureResponse.new(consumer_id, 'nonce already used')
      end

      return SuccessResponse.new(consumer_id, query)
    end