* 2022-01-18 [ci skip]
[ruby-80x24.org.git] / test / openssl / test_pkey.rb
blob544340e378873f21434be07c1c96d6abf05bf3a0
1 # frozen_string_literal: true
2 require_relative "utils"
4 class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
5   def test_generic_oid_inspect
6     # RSA private key
7     rsa = Fixtures.pkey("rsa-1")
8     assert_instance_of OpenSSL::PKey::RSA, rsa
9     assert_equal "rsaEncryption", rsa.oid
10     assert_match %r{oid=rsaEncryption}, rsa.inspect
12     # X25519 private key
13     x25519_pem = <<~EOF
14     -----BEGIN PRIVATE KEY-----
15     MC4CAQAwBQYDK2VuBCIEIHcHbQpzGKV9PBbBclGyZkXfTC+H68CZKrF3+6UduSwq
16     -----END PRIVATE KEY-----
17     EOF
18     begin
19       x25519 = OpenSSL::PKey.read(x25519_pem)
20     rescue OpenSSL::PKey::PKeyError
21       # OpenSSL < 1.1.0
22       pend "X25519 is not implemented"
23     end
24     assert_instance_of OpenSSL::PKey::PKey, x25519
25     assert_equal "X25519", x25519.oid
26     assert_match %r{oid=X25519}, x25519.inspect
27   end
29   def test_s_generate_parameters
30     pkey = OpenSSL::PKey.generate_parameters("EC", {
31       "ec_paramgen_curve" => "secp384r1",
32     })
33     assert_instance_of OpenSSL::PKey::EC, pkey
34     assert_equal "secp384r1", pkey.group.curve_name
35     assert_equal nil, pkey.private_key
37     # Invalid options are checked
38     assert_raise(OpenSSL::PKey::PKeyError) {
39       OpenSSL::PKey.generate_parameters("EC", "invalid" => "option")
40     }
42     # Parameter generation callback is called
43     cb_called = []
44     assert_raise(RuntimeError) {
45       OpenSSL::PKey.generate_parameters("DSA") { |*args|
46         cb_called << args
47         raise "exit!" if cb_called.size == 3
48       }
49     }
50     assert_not_empty cb_called
51   end
53   def test_s_generate_key
54     assert_raise(OpenSSL::PKey::PKeyError) {
55       # DSA key pair cannot be generated without parameters
56       OpenSSL::PKey.generate_key("DSA")
57     }
58     pkey_params = OpenSSL::PKey.generate_parameters("EC", {
59       "ec_paramgen_curve" => "secp384r1",
60     })
61     pkey = OpenSSL::PKey.generate_key(pkey_params)
62     assert_instance_of OpenSSL::PKey::EC, pkey
63     assert_equal "secp384r1", pkey.group.curve_name
64     assert_not_equal nil, pkey.private_key
65   end
67   def test_hmac_sign_verify
68     pkey = OpenSSL::PKey.generate_key("HMAC", { "key" => "abcd" })
70     hmac = OpenSSL::HMAC.new("abcd", "SHA256").update("data").digest
71     assert_equal hmac, pkey.sign("SHA256", "data")
73     # EVP_PKEY_HMAC does not support verify
74     assert_raise(OpenSSL::PKey::PKeyError) {
75       pkey.verify("SHA256", "data", hmac)
76     }
77   end
79   def test_ed25519
80     # Test vector from RFC 8032 Section 7.1 TEST 2
81     priv_pem = <<~EOF
82     -----BEGIN PRIVATE KEY-----
83     MC4CAQAwBQYDK2VwBCIEIEzNCJso/5banbbDRuwRTg9bijGfNaumJNqM9u1PuKb7
84     -----END PRIVATE KEY-----
85     EOF
86     pub_pem = <<~EOF
87     -----BEGIN PUBLIC KEY-----
88     MCowBQYDK2VwAyEAPUAXw+hDiVqStwqnTRt+vJyYLM8uxJaMwM1V8Sr0Zgw=
89     -----END PUBLIC KEY-----
90     EOF
91     begin
92       priv = OpenSSL::PKey.read(priv_pem)
93       pub = OpenSSL::PKey.read(pub_pem)
94     rescue OpenSSL::PKey::PKeyError
95       # OpenSSL < 1.1.1
96       pend "Ed25519 is not implemented"
97     end
98     assert_instance_of OpenSSL::PKey::PKey, priv
99     assert_instance_of OpenSSL::PKey::PKey, pub
100     assert_equal priv_pem, priv.private_to_pem
101     assert_equal pub_pem, priv.public_to_pem
102     assert_equal pub_pem, pub.public_to_pem
104     sig = [<<~EOF.gsub(/[^0-9a-f]/, "")].pack("H*")
105     92a009a9f0d4cab8720e820b5f642540
106     a2b27b5416503f8fb3762223ebdb69da
107     085ac1e43e15996e458f3613d0f11d8c
108     387b2eaeb4302aeeb00d291612bb0c00
109     EOF
110     data = ["72"].pack("H*")
111     assert_equal sig, priv.sign(nil, data)
112     assert_equal true, priv.verify(nil, sig, data)
113     assert_equal true, pub.verify(nil, sig, data)
114     assert_equal false, pub.verify(nil, sig, data.succ)
116     # PureEdDSA wants nil as the message digest
117     assert_raise(OpenSSL::PKey::PKeyError) { priv.sign("SHA512", data) }
118     assert_raise(OpenSSL::PKey::PKeyError) { pub.verify("SHA512", sig, data) }
120     # Ed25519 pkey type does not support key derivation
121     assert_raise(OpenSSL::PKey::PKeyError) { priv.derive(pub) }
122   end
124   def test_x25519
125     # Test vector from RFC 7748 Section 6.1
126     alice_pem = <<~EOF
127     -----BEGIN PRIVATE KEY-----
128     MC4CAQAwBQYDK2VuBCIEIHcHbQpzGKV9PBbBclGyZkXfTC+H68CZKrF3+6UduSwq
129     -----END PRIVATE KEY-----
130     EOF
131     bob_pem = <<~EOF
132     -----BEGIN PUBLIC KEY-----
133     MCowBQYDK2VuAyEA3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08=
134     -----END PUBLIC KEY-----
135     EOF
136     shared_secret = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
137     begin
138       alice = OpenSSL::PKey.read(alice_pem)
139       bob = OpenSSL::PKey.read(bob_pem)
140     rescue OpenSSL::PKey::PKeyError
141       # OpenSSL < 1.1.0
142       pend "X25519 is not implemented"
143     end
144     assert_instance_of OpenSSL::PKey::PKey, alice
145     assert_equal alice_pem, alice.private_to_pem
146     assert_equal bob_pem, bob.public_to_pem
147     assert_equal [shared_secret].pack("H*"), alice.derive(bob)
148   end
150   def test_compare?
151     key1 = Fixtures.pkey("rsa1024")
152     key2 = Fixtures.pkey("rsa1024")
153     key3 = Fixtures.pkey("rsa2048")
154     key4 = Fixtures.pkey("dh-1")
156     assert_equal(true, key1.compare?(key2))
157     assert_equal(true, key1.public_key.compare?(key2))
158     assert_equal(true, key2.compare?(key1))
159     assert_equal(true, key2.public_key.compare?(key1))
161     assert_equal(false, key1.compare?(key3))
163     assert_raise(TypeError) do
164       key1.compare?(key4)
165     end
166   end
168   def test_to_text
169     rsa = Fixtures.pkey("rsa1024")
170     assert_include rsa.to_text, "publicExponent"
171   end