diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-14 08:59:02 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-14 08:59:02 +0000 |
commit | 269503b544247b5b3e30dbe60a0bab4f2ca00e4e (patch) | |
tree | a6d0a3a9b34017c4c84d997152a3aaf3086e1ce1 /lib/rubygems/security | |
parent | 2614d9ba2fb5ad171200cccc88f42fa659b527c6 (diff) |
Revert r42938 "* lib/rubygems: Update to RubyGems 2.1.3"
It breaks build.
http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20130913T200302Z.diff.html.gz
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42941 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems/security')
-rw-r--r-- | lib/rubygems/security/policy.rb | 49 | ||||
-rw-r--r-- | lib/rubygems/security/signer.rb | 24 |
2 files changed, 61 insertions, 12 deletions
diff --git a/lib/rubygems/security/policy.rb b/lib/rubygems/security/policy.rb index 467ee932b5..7238b2e477 100644 --- a/lib/rubygems/security/policy.rb +++ b/lib/rubygems/security/policy.rb @@ -1,3 +1,5 @@ +require 'rubygems/user_interaction' + ## # A Gem::Security::Policy object encapsulates the settings for verifying # signed gem files. This is the base class. You can either declare an @@ -6,6 +8,8 @@ class Gem::Security::Policy + include Gem::UserInteraction + attr_reader :name attr_accessor :only_signed @@ -175,6 +179,19 @@ class Gem::Security::Policy true end + ## + # Extracts the email or subject from +certificate+ + + def subject certificate # :nodoc: + certificate.extensions.each do |extension| + next unless extension.oid == 'subjectAltName' + + return extension.value + end + + certificate.subject.to_s + end + def inspect # :nodoc: ("[Policy: %s - data: %p signer: %p chain: %p root: %p " + "signed-only: %p trusted-only: %p]") % [ @@ -184,16 +201,24 @@ class Gem::Security::Policy end ## - # Verifies the certificate +chain+ is valid, the +digests+ match the - # signatures +signatures+ created by the signer depending on the +policy+ - # settings. + # For +full_name+, verifies the certificate +chain+ is valid, the +digests+ + # match the signatures +signatures+ created by the signer depending on the + # +policy+ settings. # # If +key+ is given it is used to validate the signing certificate. - def verify chain, key = nil, digests = {}, signatures = {} - if @only_signed and signatures.empty? then - raise Gem::Security::Exception, - "unsigned gems are not allowed by the #{name} policy" + def verify chain, key = nil, digests = {}, signatures = {}, + full_name = '(unknown)' + if signatures.empty? then + if @only_signed then + raise Gem::Security::Exception, + "unsigned gems are not allowed by the #{name} policy" + elsif digests.empty? then + # lack of signatures is irrelevant if there is nothing to check + # against + else + alert_warning "#{full_name} is not signed" + end end opt = @opt @@ -222,7 +247,13 @@ class Gem::Security::Policy check_root chain, time if @verify_root - check_trust chain, digester, trust_dir if @only_trusted + if @only_trusted then + check_trust chain, digester, trust_dir + elsif signatures.empty? and digests.empty? then + # trust is irrelevant if there's no signatures to verify + else + alert_warning "#{subject signer} is not trusted for #{full_name}" + end signatures.each do |file, _| digest = signer_digests[file] @@ -252,7 +283,7 @@ class Gem::Security::Policy OpenSSL::X509::Certificate.new cert_pem end - verify chain, nil, digests, signatures + verify chain, nil, digests, signatures, spec.full_name true end diff --git a/lib/rubygems/security/signer.rb b/lib/rubygems/security/signer.rb index 78455c0732..bb1eae7cf2 100644 --- a/lib/rubygems/security/signer.rb +++ b/lib/rubygems/security/signer.rb @@ -29,7 +29,7 @@ class Gem::Security::Signer # +chain+ containing X509 certificates, encoding certificates or paths to # certificates. - def initialize key, cert_chain + def initialize key, cert_chain, passphrase = nil @cert_chain = cert_chain @key = key @@ -46,7 +46,7 @@ class Gem::Security::Signer @digest_algorithm = Gem::Security::DIGEST_ALGORITHM @digest_name = Gem::Security::DIGEST_NAME - @key = OpenSSL::PKey::RSA.new File.read @key if + @key = OpenSSL::PKey::RSA.new File.read(@key), passphrase if @key and not OpenSSL::PKey::RSA === @key if @cert_chain then @@ -63,6 +63,22 @@ class Gem::Security::Signer 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. @@ -89,7 +105,9 @@ class Gem::Security::Signer re_sign_key end - Gem::Security::SigningPolicy.verify @cert_chain, @key + full_name = extract_name @cert_chain.last + + Gem::Security::SigningPolicy.verify @cert_chain, @key, {}, {}, full_name @key.sign @digest_algorithm.new, data end |