summaryrefslogtreecommitdiff
path: root/test/rubygems/test_gem_security_signer.rb
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-29 06:52:18 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-29 06:52:18 +0000
commit9694bb8cac12969300692dac5a1cf7aa4e3a46cd (patch)
treec3cb423d701f7049ba9382de052e2a937cd1302d /test/rubygems/test_gem_security_signer.rb
parent3f606b7063fc7a8b191556365ad343a314719a8d (diff)
* lib/rubygems*: Updated to RubyGems 2.0
* test/rubygems*: ditto. * common.mk (prelude): Updated for RubyGems 2.0 source rearrangement. * tool/change_maker.rb: Allow invalid UTF-8 characters in source files. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37976 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/rubygems/test_gem_security_signer.rb')
-rw-r--r--test/rubygems/test_gem_security_signer.rb189
1 files changed, 189 insertions, 0 deletions
diff --git a/test/rubygems/test_gem_security_signer.rb b/test/rubygems/test_gem_security_signer.rb
new file mode 100644
index 0000000000..cf9ea2196d
--- /dev/null
+++ b/test/rubygems/test_gem_security_signer.rb
@@ -0,0 +1,189 @@
+require 'rubygems/test_case'
+
+class TestGemSecuritySigner < Gem::TestCase
+
+ ALTERNATE_KEY = load_key 'alternate'
+ CHILD_KEY = load_key 'child'
+ GRANDCHILD_KEY = load_key 'grandchild'
+
+ CHILD_CERT = load_cert 'child'
+ GRANDCHILD_CERT = load_cert 'grandchild'
+ EXPIRED_CERT = load_cert 'expired'
+
+ def setup
+ super
+
+ @cert_file =
+ if 32 == (Time.at(2**32) rescue 32) then
+ File.expand_path 'test/rubygems/public_cert_32.pem', @current_dir
+ else
+ File.expand_path 'test/rubygems/public_cert.pem', @current_dir
+ end
+ end
+
+ def test_initialize
+ signer = Gem::Security::Signer.new nil, nil
+
+ assert_nil signer.key
+ assert_nil signer.cert_chain
+ end
+
+ def test_initialize_cert_chain_empty
+ signer = Gem::Security::Signer.new PUBLIC_KEY, []
+
+ assert_empty signer.cert_chain
+ end
+
+ def test_initialize_cert_chain_mixed
+ signer = Gem::Security::Signer.new nil, [@cert_file, CHILD_CERT]
+
+ assert_equal [PUBLIC_CERT, CHILD_CERT].map { |c| c.to_pem },
+ signer.cert_chain.map { |c| c.to_pem }
+ end
+
+ def test_initialize_cert_chain_invalid
+ assert_raises OpenSSL::X509::CertificateError do
+ Gem::Security::Signer.new nil, ['garbage']
+ end
+ end
+
+ def test_initialize_cert_chain_path
+ signer = Gem::Security::Signer.new nil, [@cert_file]
+
+ assert_equal [PUBLIC_CERT].map { |c| c.to_pem },
+ signer.cert_chain.map { |c| c.to_pem }
+ end
+
+ def test_initialize_default
+ private_key_path = File.join Gem.user_home, 'gem-private_key.pem'
+ Gem::Security.write PRIVATE_KEY, private_key_path
+
+ public_cert_path = File.join Gem.user_home, 'gem-public_cert.pem'
+ Gem::Security.write PUBLIC_CERT, public_cert_path
+
+ signer = Gem::Security::Signer.new nil, nil
+
+ assert_equal PRIVATE_KEY.to_pem, signer.key.to_pem
+ assert_equal [PUBLIC_CERT.to_pem], signer.cert_chain.map { |c| c.to_pem }
+ end
+
+ def test_initialize_key_path
+ key_file = File.expand_path 'test/rubygems/private_key.pem', @current_dir
+
+ signer = Gem::Security::Signer.new key_file, nil
+
+ assert_equal PRIVATE_KEY.to_s, signer.key.to_s
+ end
+
+ def test_load_cert_chain
+ Gem::Security.trust_dir.trust_cert PUBLIC_CERT
+
+ signer = Gem::Security::Signer.new nil, []
+ signer.cert_chain.replace [CHILD_CERT]
+
+ signer.load_cert_chain
+
+ assert_equal [PUBLIC_CERT.to_pem, CHILD_CERT.to_pem],
+ signer.cert_chain.map { |c| c.to_pem }
+ end
+
+ def test_load_cert_chain_broken
+ Gem::Security.trust_dir.trust_cert CHILD_CERT
+
+ signer = Gem::Security::Signer.new nil, []
+ signer.cert_chain.replace [GRANDCHILD_CERT]
+
+ signer.load_cert_chain
+
+ assert_equal [CHILD_CERT.to_pem, GRANDCHILD_CERT.to_pem],
+ signer.cert_chain.map { |c| c.to_pem }
+ end
+
+ def test_sign
+ signer = Gem::Security::Signer.new PRIVATE_KEY, [PUBLIC_CERT]
+
+ signature = signer.sign 'hello'
+
+ expected = <<-EXPECTED
+oZXzQRdq0mJpAghICQvjvlB7ZyZtE4diL5jce0Fa20PkLjOvDgpuZCs6Ppu5
+LtG89EQMMBHsAyc8NMCd4oWm6Q==
+ EXPECTED
+
+ assert_equal expected, [signature].pack('m')
+ end
+
+ def test_sign_expired
+ signer = Gem::Security::Signer.new PRIVATE_KEY, [EXPIRED_CERT]
+
+ assert_raises Gem::Security::Exception do
+ signer.sign 'hello'
+ end
+ end
+
+ def test_sign_expired_auto_update
+ FileUtils.mkdir_p Gem.user_home, :mode => 0700
+
+ private_key_path = File.join(Gem.user_home, 'gem-private_key.pem')
+ Gem::Security.write PRIVATE_KEY, private_key_path
+
+ cert_path = File.join Gem.user_home, 'gem-public_cert.pem'
+ Gem::Security.write EXPIRED_CERT, cert_path
+
+ signer = Gem::Security::Signer.new PRIVATE_KEY, [EXPIRED_CERT]
+
+ signer.sign 'hello'
+
+ cert = OpenSSL::X509::Certificate.new File.read cert_path
+
+ refute_equal EXPIRED_CERT.to_pem, cert.to_pem
+ assert_in_delta Time.now, cert.not_before, 10
+
+ expiry = EXPIRED_CERT.not_after.strftime "%Y%m%d%H%M%S"
+
+ expired_path =
+ File.join Gem.user_home, "gem-public_cert.pem.expired.#{expiry}"
+
+ assert_path_exists expired_path
+ assert_equal EXPIRED_CERT.to_pem, File.read(expired_path)
+ end
+
+ def test_sign_expired_auto_update_exists
+ FileUtils.mkdir_p Gem.user_home, :mode => 0700
+
+ expiry = EXPIRED_CERT.not_after.strftime "%Y%m%d%H%M%S"
+ expired_path =
+ File.join Gem.user_home, "gem-public_cert.pem.expired.#{expiry}"
+
+ Gem::Security.write EXPIRED_CERT, expired_path
+
+ private_key_path = File.join(Gem.user_home, 'gem-private_key.pem')
+ Gem::Security.write PRIVATE_KEY, private_key_path
+
+ cert_path = File.join Gem.user_home, 'gem-public_cert.pem'
+ Gem::Security.write EXPIRED_CERT, cert_path
+
+ signer = Gem::Security::Signer.new PRIVATE_KEY, [EXPIRED_CERT]
+
+ e = assert_raises Gem::Security::Exception do
+ signer.sign 'hello'
+ end
+
+ assert_match %r%certificate /CN=nobody/DC=example not valid%, e.message
+ end
+
+ def test_sign_no_key
+ signer = Gem::Security::Signer.new nil, nil
+
+ assert_nil signer.sign 'stuff'
+ end
+
+ def test_sign_wrong_key
+ signer = Gem::Security::Signer.new ALTERNATE_KEY, [PUBLIC_CERT]
+
+ assert_raises Gem::Security::Exception do
+ signer.sign 'hello'
+ end
+ end
+
+end
+