module Hoe::Signing

def check_key_task # :nodoc:

:nodoc:
def check_key_task # :nodoc:
  with_config do |config, _path|
    break unless config["signing_cert_file"]
    pub_key = File.expand_path config["signing_cert_file"].to_s
    c = OpenSSL::X509::Certificate.new File.read pub_key
    t = c.not_after
    if t < Time.now then
      warn "Gem signing certificate has expired"
    else
      warn "Gem signing certificate has NOT expired. Carry on."
    end
  end
end

def define_signing_tasks

def define_signing_tasks
  set_up_signing
  desc "Generate a key for signing your gems."
  task :generate_key do
    generate_key_task
  end
  desc "Check pubilc key for signing your gems."
  task :check_key do
    check_key_task
  end
rescue NameError
  warn "Couldn't set up signing (openssl error?). Skipping."
end

def generate_key_task # :nodoc:

:nodoc:
def generate_key_task # :nodoc:
  email = Array(spec.email)
  abort "No email in your gemspec" if email.nil? or email.empty?
  key_file = with_config { |config, _| config["signing_key_file"] }
  cert_file = with_config { |config, _| config["signing_cert_file"] }
  if key_file.nil? or cert_file.nil? then
    ENV["SHOW_EDITOR"] ||= "no"
    Rake::Task["config_hoe"].invoke
    key_file = with_config { |config, _| config["signing_key_file"] }
    cert_file = with_config { |config, _| config["signing_cert_file"] }
  end
  key_file = File.expand_path key_file
  cert_file = File.expand_path cert_file
  unless File.exist? key_file then
    puts "Generating certificate"
    if File.exist? key_file then
      abort "Have #{key_file} but no #{cert_file}, aborting as a precaution"
    end
    warn "NOTICE: using #{email.first} for certificate" if email.size > 1
    sh "gem cert --build #{email.first}"
    mv "gem-private_key.pem", key_file, :verbose => true
    mv "gem-public_cert.pem", cert_file, :verbose => true
    puts "Installed key and certificate."
  end
  puts "Key file = #{key_file}"
  puts "Cert file = #{cert_file}"
  puts
  puts "Until rubygems.org has a better strategy for signing, that's"
  puts "the best we can do at this point."
end

def set_up_signing # :nodoc:

:nodoc:
def set_up_signing # :nodoc:
  signing_key = nil
  cert_chain = []
  with_config do |config, _path|
    break unless config["signing_key_file"] and config["signing_cert_file"]
    key_file = File.expand_path config["signing_key_file"].to_s
    signing_key = key_file if File.exist? key_file
    cert_file = File.expand_path config["signing_cert_file"].to_s
    cert_chain << cert_file if File.exist? cert_file
  end
  if signing_key and cert_chain then
    passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
    spec.signing_key = OpenSSL::PKey::RSA.new(File.read(signing_key), passphrase)
    spec.cert_chain = cert_chain
  end
end