\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /proc/self/root/opt/chef.upgrade/embedded/lib/ruby/site_ruby/2.3.0/rubygems/security/

Viewing File: signer.rb

# frozen_string_literal: true
##
# Basic OpenSSL-based package signing class.

class Gem::Security::Signer

  ##
  # The chain of certificates for signing including the signing certificate

  attr_accessor :cert_chain

  ##
  # The private key for the signing certificate

  attr_accessor :key

  ##
  # The digest algorithm used to create the signature

  attr_reader :digest_algorithm

  ##
  # The name of the digest algorithm, used to pull digests out of the hash by
  # name.

  attr_reader :digest_name # :nodoc:

  ##
  # Creates a new signer with an RSA +key+ or path to a key, and a certificate
  # +chain+ containing X509 certificates, encoding certificates or paths to
  # certificates.

  def initialize key, cert_chain, passphrase = nil
    @cert_chain = cert_chain
    @key        = key

    unless @key then
      default_key  = File.join Gem.default_key_path
      @key = default_key if File.exist? default_key
    end

    unless @cert_chain then
      default_cert = File.join Gem.default_cert_path
      @cert_chain = [default_cert] if File.exist? default_cert
    end

    @digest_algorithm = Gem::Security::DIGEST_ALGORITHM
    @digest_name      = Gem::Security::DIGEST_NAME

    @key = OpenSSL::PKey::RSA.new File.read(@key), passphrase if
      @key and not OpenSSL::PKey::RSA === @key

    if @cert_chain then
      @cert_chain = @cert_chain.compact.map do |cert|
        next cert if OpenSSL::X509::Certificate === cert

        cert = File.read cert if File.exist? cert

        OpenSSL::X509::Certificate.new cert
      end

      load_cert_chain
    end
  end

  ##
  # Extracts the full name of +cert+.  If the certificate has a subjectAltName
  # this value is preferred, otherwise the subject is used.

  def extract_name cert # :nodoc:
    subject_alt_name = cert.extensions.find { |e| 'subjectAltName' == e.oid }

    if subject_alt_name then
      /\Aemail:/ =~ subject_alt_name.value

      $' || subject_alt_name.value
    else
      cert.subject
    end
  end

  ##
  # Loads any missing issuers in the cert chain from the trusted certificates.
  #
  # If the issuer does not exist it is ignored as it will be checked later.

  def load_cert_chain # :nodoc:
    return if @cert_chain.empty?

    while @cert_chain.first.issuer.to_s != @cert_chain.first.subject.to_s do
      issuer = Gem::Security.trust_dir.issuer_of @cert_chain.first

      break unless issuer # cert chain is verified later

      @cert_chain.unshift issuer
    end
  end

  ##
  # Sign data with given digest algorithm

  def sign data
    return unless @key

    raise Gem::Security::Exception, 'no certs provided' if @cert_chain.empty?

    if @cert_chain.length == 1 and @cert_chain.last.not_after < Time.now then
      re_sign_key
    end

    full_name = extract_name @cert_chain.last

    Gem::Security::SigningPolicy.verify @cert_chain, @key, {}, {}, full_name

    @key.sign @digest_algorithm.new, data
  end

  ##
  # Attempts to re-sign the private key if the signing certificate is expired.
  #
  # The key will be re-signed if:
  # * The expired certificate is self-signed
  # * The expired certificate is saved at ~/.gem/gem-public_cert.pem
  # * There is no file matching the expiry date at
  #   ~/.gem/gem-public_cert.pem.expired.%Y%m%d%H%M%S
  #
  # If the signing certificate can be re-signed the expired certificate will
  # be saved as ~/.gem/gem-public_cert.pem.expired.%Y%m%d%H%M%S where the
  # expiry time (not after) is used for the timestamp.

  def re_sign_key # :nodoc:
    old_cert = @cert_chain.last

    disk_cert_path = File.join Gem.default_cert_path
    disk_cert = File.read disk_cert_path rescue nil
    disk_key  =
      File.read File.join(Gem.default_key_path) rescue nil

    if disk_key == @key.to_pem and disk_cert == old_cert.to_pem then
      expiry = old_cert.not_after.strftime '%Y%m%d%H%M%S'
      old_cert_file = "gem-public_cert.pem.expired.#{expiry}"
      old_cert_path = File.join Gem.user_home, ".gem", old_cert_file

      unless File.exist? old_cert_path then
        Gem::Security.write old_cert, old_cert_path

        cert = Gem::Security.re_sign old_cert, @key

        Gem::Security.write cert, disk_cert_path

        @cert_chain = [cert]
      end
    end
  end

end