[前][次][番号順一覧][スレッド一覧]

ruby-changes:27101

From: drbrain <ko1@a...>
Date: Fri, 8 Feb 2013 12:07:51 +0900 (JST)
Subject: [ruby-changes:27101] drbrain:r39153 (trunk): * lib/rubygems/security/policy.rb: Raise proper exceptions when

drbrain	2013-02-08 11:58:19 +0900 (Fri, 08 Feb 2013)

  New Revision: 39153

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=39153

  Log:
    * 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.

  Modified files:
    trunk/ChangeLog
    trunk/lib/rubygems/security/policy.rb
    trunk/test/rubygems/test_gem_security_policy.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 39152)
+++ ChangeLog	(revision 39153)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Feb  8 11:53:33 2013  Eric Hodel  <drbrain@s...>
+
+	* 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.
+
 Fri Feb  8 10:44:44 2013  Eric Hodel  <drbrain@s...>
 
 	* test/rubygems/test_gem_dependency_installer.rb:  Improve coverage of
Index: lib/rubygems/security/policy.rb
===================================================================
--- lib/rubygems/security/policy.rb	(revision 39152)
+++ lib/rubygems/security/policy.rb	(revision 39153)
@@ -49,13 +49,18 @@ class Gem::Security::Policy https://github.com/ruby/ruby/blob/trunk/lib/rubygems/security/policy.rb#L49
   # 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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/security/policy.rb#L79
   # 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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/security/policy.rb#L105
   # 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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/security/policy.rb#L123
   # +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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/security/policy.rb#L142
   # 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
Index: test/rubygems/test_gem_security_policy.rb
===================================================================
--- test/rubygems/test_gem_security_policy.rb	(revision 39152)
+++ test/rubygems/test_gem_security_policy.rb	(revision 39153)
@@ -34,6 +34,7 @@ class TestGemSecurityPolicy < Gem::TestC https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_security_policy.rb#L34
     @no        = Gem::Security::NoSecurity
     @almost_no = Gem::Security::AlmostNoSecurity
     @low       = Gem::Security::LowSecurity
+    @medium    = Gem::Security::MediumSecurity
     @high      = Gem::Security::HighSecurity
 
     @chain = Gem::Security::Policy.new(
@@ -85,6 +86,14 @@ class TestGemSecurityPolicy < Gem::TestC https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_security_policy.rb#L86
     assert @chain.check_chain chain, Time.now
   end
 
+  def test_check_chain_empty_chain
+    e = assert_raises Gem::Security::Exception do
+      @chain.check_chain [], Time.now
+    end
+
+    assert_equal 'empty signing chain', e.message
+  end
+
   def test_check_chain_invalid
     chain = [PUBLIC_CERT, CHILD_CERT, INVALIDCHILD_CERT]
 
@@ -97,6 +106,14 @@ class TestGemSecurityPolicy < Gem::TestC https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_security_policy.rb#L106
                  "was not issued by #{CHILD_CERT.subject}", e.message
   end
 
+  def test_check_chain_no_chain
+    e = assert_raises Gem::Security::Exception do
+      @chain.check_chain nil, Time.now
+    end
+
+    assert_equal 'missing signing chain', e.message
+  end
+
   def test_check_cert
     assert @low.check_cert(PUBLIC_CERT, nil, Time.now)
   end
@@ -135,10 +152,28 @@ class TestGemSecurityPolicy < Gem::TestC https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_security_policy.rb#L152
     assert @low.check_cert(CHILD_CERT, PUBLIC_CERT, Time.now)
   end
 
+  def test_check_cert_no_signer
+    e = assert_raises Gem::Security::Exception do
+      @high.check_cert(nil, nil, Time.now)
+    end
+
+    assert_equal 'missing signing certificate', e.message
+  end
+
   def test_check_key
     assert @almost_no.check_key(PUBLIC_CERT, PRIVATE_KEY)
   end
 
+  def test_check_key_no_signer
+    assert @almost_no.check_key(nil, nil)
+
+    e = assert_raises Gem::Security::Exception do
+      @high.check_key(nil, nil)
+    end
+
+    assert_equal 'missing key or signature', e.message
+  end
+
   def test_check_key_wrong_key
     e = assert_raises Gem::Security::Exception do
       @almost_no.check_key(PUBLIC_CERT, ALTERNATE_KEY)
@@ -154,6 +189,14 @@ class TestGemSecurityPolicy < Gem::TestC https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_security_policy.rb#L189
     assert @chain.check_root chain, Time.now
   end
 
+  def test_check_root_empty_chain
+    e = assert_raises Gem::Security::Exception do
+      @chain.check_root [], Time.now
+    end
+
+    assert_equal 'missing root certificate', e.message
+  end
+
   def test_check_root_invalid_signer
     chain = [INVALID_SIGNER_CERT]
 
@@ -178,6 +221,14 @@ class TestGemSecurityPolicy < Gem::TestC https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_security_policy.rb#L221
                  e.message
   end
 
+  def test_check_root_no_chain
+    e = assert_raises Gem::Security::Exception do
+      @chain.check_root nil, Time.now
+    end
+
+    assert_equal 'missing signing chain', e.message
+  end
+
   def test_check_trust
     Gem::Security.trust_dir.trust_cert PUBLIC_CERT
 
@@ -190,6 +241,14 @@ class TestGemSecurityPolicy < Gem::TestC https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_security_policy.rb#L241
     assert @high.check_trust [PUBLIC_CERT, CHILD_CERT], @sha1, @trust_dir
   end
 
+  def test_check_trust_empty_chain
+    e = assert_raises Gem::Security::Exception do
+      @chain.check_trust [], @sha1, @trust_dir
+    end
+
+    assert_equal 'missing root certificate', e.message
+  end
+
   def test_check_trust_mismatch
     Gem::Security.trust_dir.trust_cert PUBLIC_CERT
 
@@ -201,6 +260,14 @@ class TestGemSecurityPolicy < Gem::TestC https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_security_policy.rb#L260
                  "does not match signing root certificate checksum", e.message
   end
 
+  def test_check_trust_no_chain
+    e = assert_raises Gem::Security::Exception do
+      @chain.check_trust nil, @sha1, @trust_dir
+    end
+
+    assert_equal 'missing signing chain', e.message
+  end
+
   def test_check_trust_no_trust
     e = assert_raises Gem::Security::Exception do
       @high.check_trust [PUBLIC_CERT], @sha1, @trust_dir

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]