diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-02-08 02:58:19 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-02-08 02:58:19 +0000 |
commit | d2be12ef6171f75a074aca8caaeaf834e1f2aac8 (patch) | |
tree | 3932c9c3040bc8b306f4337004ccab6bc48dd93d /lib/rubygems | |
parent | 16f6500cb2f81a66e831dd9d878ff56e81f1ab43 (diff) |
* lib/rubygems/security/policy.rb: Raise proper exceptions when
verifying unsigned gems (instead of crashing).
* test/rubygems/test_gem_security_policy.rb: Tests for the above.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39153 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems')
-rw-r--r-- | lib/rubygems/security/policy.rb | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/lib/rubygems/security/policy.rb b/lib/rubygems/security/policy.rb index d1539e4985..f3e4568117 100644 --- a/lib/rubygems/security/policy.rb +++ b/lib/rubygems/security/policy.rb @@ -49,13 +49,18 @@ class Gem::Security::Policy # and is valid for the given +time+. def check_chain chain, time - chain.each_cons 2 do |issuer, cert| - check_cert cert, issuer, time - end + raise Gem::Security::Exception, 'missing signing chain' unless chain + raise Gem::Security::Exception, 'empty signing chain' if chain.empty? - true - rescue Gem::Security::Exception => e - raise Gem::Security::Exception, "invalid signing chain: #{e.message}" + begin + chain.each_cons 2 do |issuer, cert| + check_cert cert, issuer, time + end + + true + rescue Gem::Security::Exception => e + raise Gem::Security::Exception, "invalid signing chain: #{e.message}" + end end ## @@ -74,6 +79,9 @@ class Gem::Security::Policy # If the +issuer+ is +nil+ no verification is performed. def check_cert signer, issuer, time + raise Gem::Security::Exception, 'missing signing certificate' unless + signer + message = "certificate #{signer.subject}" if not_before = signer.not_before and not_before > time then @@ -97,6 +105,12 @@ class Gem::Security::Policy # Ensures the public key of +key+ matches the public key in +signer+ def check_key signer, key + unless signer and key then + return true unless @only_signed + + raise Gem::Security::Exception, 'missing key or signature' + end + raise Gem::Security::Exception, "certificate #{signer.subject} does not match the signing key" unless signer.public_key.to_pem == key.public_key.to_pem @@ -109,8 +123,12 @@ class Gem::Security::Policy # +time+. def check_root chain, time + raise Gem::Security::Exception, 'missing signing chain' unless chain + root = chain.first + raise Gem::Security::Exception, 'missing root certificate' unless root + raise Gem::Security::Exception, "root certificate #{root.subject} is not self-signed " + "(issuer #{root.issuer})" if @@ -124,8 +142,12 @@ class Gem::Security::Policy # the digests of the two certificates match according to +digester+ def check_trust chain, digester, trust_dir + raise Gem::Security::Exception, 'missing signing chain' unless chain + root = chain.first + raise Gem::Security::Exception, 'missing root certificate' unless root + path = Gem::Security.trust_dir.cert_path root unless File.exist? path then |