summaryrefslogtreecommitdiff
path: root/lib/rubygems/security/signer.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rubygems/security/signer.rb')
-rw-r--r--lib/rubygems/security/signer.rb41
1 files changed, 28 insertions, 13 deletions
diff --git a/lib/rubygems/security/signer.rb b/lib/rubygems/security/signer.rb
index 0c6ef60a9a..1ee9c31be6 100644
--- a/lib/rubygems/security/signer.rb
+++ b/lib/rubygems/security/signer.rb
@@ -2,8 +2,12 @@
##
# Basic OpenSSL-based package signing class.
+require "rubygems/user_interaction"
+
class Gem::Security::Signer
+ include Gem::UserInteraction
+
##
# The chain of certificates for signing including the signing certificate
@@ -33,6 +37,7 @@ class Gem::Security::Signer
def initialize key, cert_chain, passphrase = nil
@cert_chain = cert_chain
@key = key
+ @passphrase = passphrase
unless @key then
default_key = File.join Gem.default_key_path
@@ -47,8 +52,10 @@ class Gem::Security::Signer
@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 @key && !@key.is_a?(OpenSSL::PKey::RSA)
+ @passphrase ||= ask_for_password("Enter PEM pass phrase:")
+ @key = OpenSSL::PKey::RSA.new(File.read(@key), @passphrase)
+ end
if @cert_chain then
@cert_chain = @cert_chain.compact.map do |cert|
@@ -121,6 +128,7 @@ class Gem::Security::Signer
# The key will be re-signed if:
# * The expired certificate is self-signed
# * The expired certificate is saved at ~/.gem/gem-public_cert.pem
+ # and the private key is saved at ~/.gem/gem-private_key.pem
# * There is no file matching the expiry date at
# ~/.gem/gem-public_cert.pem.expired.%Y%m%d%H%M%S
#
@@ -131,22 +139,29 @@ class Gem::Security::Signer
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
+ disk_cert_path = File.join(Gem.default_cert_path)
+ disk_cert = File.read(disk_cert_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'
+ disk_key_path = File.join(Gem.default_key_path)
+ disk_key =
+ OpenSSL::PKey::RSA.new(File.read(disk_key_path), @passphrase) rescue nil
+
+ return unless disk_key
+
+ if disk_key.to_pem == @key.to_pem && disk_cert == old_cert.to_pem
+ 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
+ old_cert_path = File.join(Gem.user_home, ".gem", old_cert_file)
+
+ unless File.exist?(old_cert_path)
+ Gem::Security.write(old_cert, old_cert_path)
- unless File.exist? old_cert_path then
- Gem::Security.write old_cert, old_cert_path
+ cert = Gem::Security.re_sign(old_cert, @key)
- cert = Gem::Security.re_sign old_cert, @key
+ Gem::Security.write(cert, disk_cert_path)
- Gem::Security.write cert, disk_cert_path
+ alert("Your cert: #{disk_cert_path} has been auto re-signed with the key: #{disk_key_path}")
+ alert("Your expired cert will be located at: #{old_cert_path}")
@cert_chain = [cert]
end