diff options
author | Jenny Shen <jenny.shen@shopify.com> | 2021-10-06 17:39:23 -0400 |
---|---|---|
committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2021-10-26 08:01:55 +0900 |
commit | 92ec010595bed29567fc08dd4d52d4c4518f0fd4 (patch) | |
tree | dd979fbf6aba6d5638153c54ca03f3363e9a8827 /test | |
parent | 10fe8495cd9568be79b4c254742eb0f667e84988 (diff) |
[rubygems/rubygems] Add support to build and sign certificates with multiple key algorithms
https://github.com/rubygems/rubygems/commit/967876f15d
Co-Authored-By: Frederik Dudzik <frederik.dudzik@shopify.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/rubygems/helper.rb | 4 | ||||
-rw-r--r-- | test/rubygems/private_ec_key.pem | 9 | ||||
-rw-r--r-- | test/rubygems/test_gem_commands_cert_command.rb | 67 | ||||
-rw-r--r-- | test/rubygems/test_gem_security.rb | 36 |
4 files changed, 106 insertions, 10 deletions
diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb index 17f7350f13..504e25ea52 100644 --- a/test/rubygems/helper.rb +++ b/test/rubygems/helper.rb @@ -1519,14 +1519,14 @@ Also, a list: end ## - # Loads an RSA private key named +key_name+ with +passphrase+ in <tt>test/rubygems/</tt> + # Loads a private key named +key_name+ with +passphrase+ in <tt>test/rubygems/</tt> def self.load_key(key_name, passphrase = nil) key_file = key_path key_name key = File.read key_file - OpenSSL::PKey::RSA.new key, passphrase + OpenSSL::PKey.read key, passphrase end ## diff --git a/test/rubygems/private_ec_key.pem b/test/rubygems/private_ec_key.pem new file mode 100644 index 0000000000..5d855d0dfc --- /dev/null +++ b/test/rubygems/private_ec_key.pem @@ -0,0 +1,9 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,4107F98A374CB8EC18F1AA4EA4B6A0DB + +BRklFxJGcz7gqQYxek8TZkt8qbPhB0FSR6nyw3SYuio/2tlT9ohs74mlK3EbG9Lt +Y4OquJbksBFmoB7fIoM4vnuIZ0Eoz2ooxn9tjhBtqJ3mVscYXwZmA3UDUWDMlviQ +Fu37OpikQv4TFA1jlmUK0LM8xmUCfUeLl0kHD17lFsz2gkO2kwg8mn/YUMOIaDOu +EnnmxbAwnZBpemQkQfpTt2mYL9gu3CcMt5gokBuGDxY= +-----END EC PRIVATE KEY----- diff --git a/test/rubygems/test_gem_commands_cert_command.rb b/test/rubygems/test_gem_commands_cert_command.rb index f722678a19..077be11d55 100644 --- a/test/rubygems/test_gem_commands_cert_command.rb +++ b/test/rubygems/test_gem_commands_cert_command.rb @@ -14,9 +14,10 @@ class TestGemCommandsCertCommand < Gem::TestCase ALTERNATE_CERT = load_cert 'alternate' EXPIRED_PUBLIC_CERT = load_cert 'expired' - ALTERNATE_KEY_FILE = key_path 'alternate' - PRIVATE_KEY_FILE = key_path 'private' - PUBLIC_KEY_FILE = key_path 'public' + ALTERNATE_KEY_FILE = key_path 'alternate' + PRIVATE_KEY_FILE = key_path 'private' + PRIVATE_EC_KEY_FILE = key_path 'private_ec' + PUBLIC_KEY_FILE = key_path 'public' ALTERNATE_CERT_FILE = cert_path 'alternate' CHILD_CERT_FILE = cert_path 'child' @@ -142,6 +143,42 @@ Added '/CN=alternate/DC=example' assert_path_exist File.join(@tempdir, 'gem-public_cert.pem') end + def test_execute_build_key_algorithm_ec_key + passphrase = 'Foo bar' + + @cmd.handle_options %W[--build nobody@example.com --key-algorithm ec] + + @build_ui = Gem::MockGemUi.new "#{passphrase}\n#{passphrase}" + + use_ui @build_ui do + @cmd.execute + end + + output = @build_ui.output.squeeze("\n").split "\n" + + assert_equal "Passphrase for your Private Key: ", + output.shift + assert_equal "Please repeat the passphrase for your Private Key: ", + output.shift + assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}", + output.shift + assert_equal "Private Key: #{File.join @tempdir, 'gem-private_key.pem'}", + output.shift + + assert_equal "Don't forget to move the key file to somewhere private!", + output.shift + + assert_empty output + assert_empty @build_ui.error + + assert_path_exist File.join(@tempdir, 'gem-private_key.pem') + + cert_path = File.join(@tempdir, 'gem-public_cert.pem') + assert_path_exist cert_path + cert = OpenSSL::X509::Certificate.new(File.read(cert_path)) + assert cert.public_key.is_a? OpenSSL::PKey::EC + end + def test_execute_build_bad_email_address passphrase = 'Foo bar' email = "nobody@" @@ -279,6 +316,28 @@ Added '/CN=alternate/DC=example' assert_path_exist File.join(@tempdir, 'gem-public_cert.pem') end + def test_execute_build_ec_key + @cmd.handle_options %W[ + --build nobody@example.com + --private-key #{PRIVATE_EC_KEY_FILE} + ] + + use_ui @ui do + @cmd.execute + end + + output = @ui.output.split "\n" + + assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}", + output.shift + + assert_empty output + assert_empty @ui.error + + assert_path_exist File.join(@tempdir, 'gem-public_cert.pem') + assert_path_not_exist File.join(@tempdir, 'gem-private_key.pem') + end + def test_execute_certificate use_ui @ui do @cmd.handle_options %W[--certificate #{PUBLIC_CERT_FILE}] @@ -742,7 +801,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis @cmd.handle_options %W[--private-key #{bad}] end - assert_equal "invalid argument: --private-key #{bad}: invalid RSA key", + assert_equal "invalid argument: --private-key #{bad}: invalid RSA, DSA, or EC key", e.message e = assert_raise OptionParser::InvalidArgument do diff --git a/test/rubygems/test_gem_security.rb b/test/rubygems/test_gem_security.rb index 2eabbea3bf..d04bd4a8bd 100644 --- a/test/rubygems/test_gem_security.rb +++ b/test/rubygems/test_gem_security.rb @@ -12,6 +12,7 @@ end class TestGemSecurity < Gem::TestCase CHILD_KEY = load_key 'child' + EC_KEY = load_key 'private_ec', 'Foo bar' ALTERNATE_CERT = load_cert 'child' CHILD_CERT = load_cert 'child' @@ -103,11 +104,38 @@ class TestGemSecurity < Gem::TestCase end def test_class_create_key - key = @SEC.create_key 1024 + key = @SEC.create_key 'rsa' assert_kind_of OpenSSL::PKey::RSA, key end + def test_class_create_key_downcases + key = @SEC.create_key 'DSA' + + assert_kind_of OpenSSL::PKey::DSA, key + end + + def test_class_create_key_raises_unknown_algorithm + e = assert_raise Gem::Security::Exception do + @SEC.create_key 'NOT_RSA' + end + + assert_equal "NOT_RSA algorithm not found. RSA, DSA, and EC algorithms are supported.", + e.message + end + + def test_class_get_public_key_rsa + pkey_pem = PRIVATE_KEY.public_key.to_pem + + assert_equal pkey_pem, @SEC.get_public_key(PRIVATE_KEY).to_pem + end + + def test_class_get_public_key_ec + pkey = @SEC.get_public_key(EC_KEY) + + assert_respond_to pkey, :to_pem + end + def test_class_email_to_name assert_equal '/CN=nobody/DC=example', @SEC.email_to_name('nobody@example').to_s @@ -259,7 +287,7 @@ class TestGemSecurity < Gem::TestCase end def test_class_write - key = @SEC.create_key 1024 + key = @SEC.create_key 'rsa' path = File.join @tempdir, 'test-private_key.pem' @@ -273,7 +301,7 @@ class TestGemSecurity < Gem::TestCase end def test_class_write_encrypted - key = @SEC.create_key 1024 + key = @SEC.create_key 'rsa' path = File.join @tempdir, 'test-private_encrypted_key.pem' @@ -289,7 +317,7 @@ class TestGemSecurity < Gem::TestCase end def test_class_write_encrypted_cipher - key = @SEC.create_key 1024 + key = @SEC.create_key 'rsa' path = File.join @tempdir, 'test-private_encrypted__with_non_default_cipher_key.pem' |