def verify_gem(signature, data, chain, time = Time.now)
      Gem.ensure_ssl_available
      cert_class = OpenSSL::X509::Certificate
      exc = Gem::Security::Exception
      chain ||= []
      chain = chain.map{ |str| cert_class.new(str) }
      signer, ch_len = chain[-1], chain.size
      
      if @verify_data
        
        dgst = @opt[:dgst_algo]
        
        
        v = signer.public_key.verify(dgst.new, signature, data)
        raise exc, "Invalid Gem Signature" unless v
        
        if @verify_signer
          
          v = signer.check_validity(nil, time)
          raise exc, "Invalid Signature: #{v[:desc]}" unless v[:is_valid]
        end
      end
      
      if @verify_chain
        
        
        (ch_len - 1).downto(1) do |i|
          issuer, cert = chain[i - 1, 2]
          v = cert.check_validity(issuer, time)
          raise exc, "%s: cert = '%s', error = '%s'" % [
              'Invalid Signing Chain', cert.subject, v[:desc]
          ] unless v[:is_valid]
        end
        
        if @verify_root
          
          root = chain[0]
          raise exc, "%s: %s (subject = '%s', issuer = '%s')" % [
              'Invalid Signing Chain Root',
              'Subject does not match Issuer for Gem Signing Chain',
              root.subject.to_s,
              root.issuer.to_s,
          ] unless root.issuer.to_s == root.subject.to_s
          
          v = root.check_validity(root, time)
          raise exc, "%s: cert = '%s', error = '%s'" % [
              'Invalid Signing Chain Root', root.subject, v[:desc]
          ] unless v[:is_valid]
          
          if @only_trusted
            
            algo = @opt[:dgst_algo]
            path = Gem::Security::Policy.trusted_cert_path(root, @opt)
            
            raise exc, "%s: cert = '%s', error = '%s'" % [
                'Untrusted Signing Chain Root',
                root.subject.to_s,
                "path \"#{path}\" does not exist",
            ] unless File.exist?(path)
            
            save_cert = OpenSSL::X509::Certificate.new(File.read(path))
            save_dgst = algo.digest(save_cert.public_key.to_s)
            
            pkey_str = root.public_key.to_s
            cert_dgst = algo.digest(pkey_str)
            
            
            raise exc, "%s: %s (saved = '%s', root = '%s')" % [
                'Invalid Signing Chain Root',
                "Saved checksum doesn't match root checksum",
                save_dgst, cert_dgst,
            ] unless save_dgst == cert_dgst
          end
        end
        
        chain.map { |cert| cert.subject }
      end
    end