aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rubygems/security
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-02-08 02:58:19 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-02-08 02:58:19 +0000
commitd2be12ef6171f75a074aca8caaeaf834e1f2aac8 (patch)
tree3932c9c3040bc8b306f4337004ccab6bc48dd93d /lib/rubygems/security
parent16f6500cb2f81a66e831dd9d878ff56e81f1ab43 (diff)
downloadruby-d2be12ef6171f75a074aca8caaeaf834e1f2aac8.tar.gz
* 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/security')
-rw-r--r--lib/rubygems/security/policy.rb34
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