Class: Gem::Security::Signer
- Inherits:
-
Object
- Object
- Gem::Security::Signer
- Defined in:
- lib/rubygems/security/signer.rb
Overview
Basic OpenSSL-based package signing class.
Instance Attribute Summary collapse
-
#cert_chain ⇒ Object
The chain of certificates for signing including the signing certificate.
-
#digest_algorithm ⇒ Object
readonly
The digest algorithm used to create the signature.
-
#digest_name ⇒ Object
readonly
The name of the digest algorithm, used to pull digests out of the hash by name.
-
#key ⇒ Object
The private key for the signing certificate.
Instance Method Summary collapse
-
#initialize(key, cert_chain) ⇒ Signer
constructor
Creates a new signer with an RSA
key
or path to a key, and a certificatechain
containing X509 certificates, encoding certificates or paths to certificates. -
#load_cert_chain ⇒ Object
Loads any missing issuers in the cert chain from the trusted certificates.
-
#re_sign_key ⇒ Object
Attempts to re-sign the private key if the signing certificate is expired.
-
#sign(data) ⇒ Object
Sign data with given digest algorithm.
Constructor Details
#initialize(key, cert_chain) ⇒ Signer
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.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/rubygems/security/signer.rb', line 32 def initialize key, cert_chain @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 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 |
Instance Attribute Details
#cert_chain ⇒ Object
The chain of certificates for signing including the signing certificate
9 10 11 |
# File 'lib/rubygems/security/signer.rb', line 9 def cert_chain @cert_chain end |
#digest_algorithm ⇒ Object (readonly)
The digest algorithm used to create the signature
19 20 21 |
# File 'lib/rubygems/security/signer.rb', line 19 def digest_algorithm @digest_algorithm end |
#digest_name ⇒ Object (readonly)
The name of the digest algorithm, used to pull digests out of the hash by name.
25 26 27 |
# File 'lib/rubygems/security/signer.rb', line 25 def digest_name @digest_name end |
#key ⇒ Object
The private key for the signing certificate
14 15 16 |
# File 'lib/rubygems/security/signer.rb', line 14 def key @key end |
Instance Method Details
#load_cert_chain ⇒ Object
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.
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/rubygems/security/signer.rb', line 70 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 |
#re_sign_key ⇒ Object
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-pubilc_cert.pem.expired.%Y%m%d%H%M%S where the expiry time (not after) is used for the timestamp.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/rubygems/security/signer.rb', line 110 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 |
#sign(data) ⇒ Object
Sign data with given digest algorithm
85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/rubygems/security/signer.rb', line 85 def sign data return unless @key if @cert_chain.length == 1 and @cert_chain.last.not_after < Time.now then re_sign_key end Gem::Security::SigningPolicy.verify @cert_chain, @key @key.sign @digest_algorithm.new, data end |