Module: Hoe::Signing

Defined in:
lib/hoe/signing.rb

Overview

Signing plugin for hoe.

Tasks Provided:

generate_key

Generate a key for signing your gems.

Extra Configuration Options:

signing_key_file

Signs your gems with this private key.

signing_cert_file

Signs your gem with this certificate.

Usage:

Run the ‘generate_key’ task. This will:

  1. Configure your ~/.hoerc.

  2. Generate a signing key and certificate.

  3. Install the private key and public certificate files into ~/.gem.

Hoe will now generate signed gems when the package task is run. If you have multiple machines you build gems on, be sure to install your key and certificate on each machine.

Keep your private key secret! Keep your private key safe!

You can provide your private key passphrase via the GEM_PRIVATE_KEY_PASSPHRASE environment variable.

To make sure your gems are signed run:

rake package; tar tf pkg/yourproject-1.2.3.gem

If your gem is signed you will see:

data.tar.gz
data.tar.gz.sig
.gz
.gz.sig

Instance Method Summary collapse

Instance Method Details

#check_key_taskObject

:nodoc:



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/hoe/signing.rb', line 84

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

#define_signing_tasksObject

Define tasks for plugin.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/hoe/signing.rb', line 48

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

#generate_key_taskObject

:nodoc:



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/hoe/signing.rb', line 100

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

#set_up_signingObject

:nodoc:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/hoe/signing.rb', line 64

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