# File lib/rubygems/package.rb, line 478
    def initialize(io, security_policy = nil)
      @io = io
      @tarreader = TarReader.new(@io)
      has_meta = false
      data_sig, meta_sig, data_dgst, meta_dgst = nil, nil, nil, nil
      dgst_algo = security_policy ? Gem::Security::OPT[:dgst_algo] : nil

      @tarreader.each do |entry|
        case entry.full_name
        when "metadata"
          @metadata = load_gemspec(entry.read)
          has_meta = true
          break
        when "metadata.gz"
          begin
            # if we have a security_policy, then pre-read the metadata file
            # and calculate it's digest
            sio = nil
            if security_policy
              Gem.ensure_ssl_available
              sio = StringIO.new(entry.read)
              meta_dgst = dgst_algo.digest(sio.string)
              sio.rewind
            end

            gzis = Zlib::GzipReader.new(sio || entry)
            # YAML wants an instance of IO
            @metadata = load_gemspec(gzis)
            has_meta = true
          ensure
            gzis.close unless gzis.nil?
          end
        when 'metadata.gz.sig'
          meta_sig = entry.read
        when 'data.tar.gz.sig'
          data_sig = entry.read
        when 'data.tar.gz'
          if security_policy
            Gem.ensure_ssl_available
            data_dgst = dgst_algo.digest(entry.read)
          end
        end
      end

      if security_policy then
        Gem.ensure_ssl_available

        # map trust policy from string to actual class (or a serialized YAML
        # file, if that exists)
        if String === security_policy then
          if Gem::Security::Policy.key? security_policy then
            # load one of the pre-defined security policies
            security_policy = Gem::Security::Policy[security_policy]
          elsif File.exist? security_policy then
            # FIXME: this doesn't work yet
            security_policy = YAML.load File.read(security_policy)
          else
            raise Gem::Exception, "Unknown trust policy '#{security_policy}'"
          end
        end

        if data_sig && data_dgst && meta_sig && meta_dgst then
          # the user has a trust policy, and we have a signed gem
          # file, so use the trust policy to verify the gem signature

          begin
            security_policy.verify_gem(data_sig, data_dgst, @metadata.cert_chain)
          rescue Exception => e
            raise "Couldn't verify data signature: #{e}"
          end

          begin
            security_policy.verify_gem(meta_sig, meta_dgst, @metadata.cert_chain)
          rescue Exception => e
            raise "Couldn't verify metadata signature: #{e}"
          end
        elsif security_policy.only_signed
          raise Gem::Exception, "Unsigned gem"
        else
          # FIXME: should display warning here (trust policy, but
          # either unsigned or badly signed gem file)
        end
      end

      @tarreader.rewind
      @fileops = Gem::FileOperations.new
      raise FormatError, "No metadata found!" unless has_meta
    end