aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2020-05-13 18:07:06 +0900
committerGitHub <noreply@github.com>2020-05-13 18:07:06 +0900
commitd669d7158266c7943d191be9dd39f3be2df7cf57 (patch)
treead243a8e2c8eb67bbb6222959ff08a96326abca4 /test
parent2cb67d71f6276875186096cfcddad3b9e4de6e8f (diff)
parent28edf6bafcfd8c80e2cb52c498db8930f8517fd1 (diff)
downloadruby-openssl-d669d7158266c7943d191be9dd39f3be2df7cf57.tar.gz
Merge pull request #329 from rhenium/ky/pkey-generic-operations
pkey: add more support for 'generic' pkey types
Diffstat (limited to 'test')
-rw-r--r--test/openssl/test_pkey.rb126
-rw-r--r--test/openssl/test_pkey_dh.rb13
-rw-r--r--test/openssl/test_pkey_ec.rb16
3 files changed, 155 insertions, 0 deletions
diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb
index 0bdc9795..5307fe5b 100644
--- a/test/openssl/test_pkey.rb
+++ b/test/openssl/test_pkey.rb
@@ -25,4 +25,130 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
assert_equal "X25519", x25519.oid
assert_match %r{oid=X25519}, x25519.inspect
end
+
+ def test_s_generate_parameters
+ # 512 is non-default; 1024 is used if 'dsa_paramgen_bits' is not specified
+ # with OpenSSL 1.1.0.
+ pkey = OpenSSL::PKey.generate_parameters("DSA", {
+ "dsa_paramgen_bits" => 512,
+ "dsa_paramgen_q_bits" => 256,
+ })
+ assert_instance_of OpenSSL::PKey::DSA, pkey
+ assert_equal 512, pkey.p.num_bits
+ assert_equal 256, pkey.q.num_bits
+ assert_equal nil, pkey.priv_key
+
+ # Invalid options are checked
+ assert_raise(OpenSSL::PKey::PKeyError) {
+ OpenSSL::PKey.generate_parameters("DSA", "invalid" => "option")
+ }
+
+ # Parameter generation callback is called
+ cb_called = []
+ assert_raise(RuntimeError) {
+ OpenSSL::PKey.generate_parameters("DSA") { |*args|
+ cb_called << args
+ raise "exit!" if cb_called.size == 3
+ }
+ }
+ assert_not_empty cb_called
+ end
+
+ def test_s_generate_key
+ assert_raise(OpenSSL::PKey::PKeyError) {
+ # DSA key pair cannot be generated without parameters
+ OpenSSL::PKey.generate_key("DSA")
+ }
+ pkey_params = OpenSSL::PKey.generate_parameters("DSA", {
+ "dsa_paramgen_bits" => 512,
+ "dsa_paramgen_q_bits" => 256,
+ })
+ pkey = OpenSSL::PKey.generate_key(pkey_params)
+ assert_instance_of OpenSSL::PKey::DSA, pkey
+ assert_equal 512, pkey.p.num_bits
+ assert_not_equal nil, pkey.priv_key
+ end
+
+ def test_hmac_sign_verify
+ pkey = OpenSSL::PKey.generate_key("HMAC", { "key" => "abcd" })
+
+ hmac = OpenSSL::HMAC.new("abcd", "SHA256").update("data").digest
+ assert_equal hmac, pkey.sign("SHA256", "data")
+
+ # EVP_PKEY_HMAC does not support verify
+ assert_raise(OpenSSL::PKey::PKeyError) {
+ pkey.verify("SHA256", "data", hmac)
+ }
+ end
+
+ def test_ed25519
+ # Test vector from RFC 8032 Section 7.1 TEST 2
+ priv_pem = <<~EOF
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIEzNCJso/5banbbDRuwRTg9bijGfNaumJNqM9u1PuKb7
+ -----END PRIVATE KEY-----
+ EOF
+ pub_pem = <<~EOF
+ -----BEGIN PUBLIC KEY-----
+ MCowBQYDK2VwAyEAPUAXw+hDiVqStwqnTRt+vJyYLM8uxJaMwM1V8Sr0Zgw=
+ -----END PUBLIC KEY-----
+ EOF
+ begin
+ priv = OpenSSL::PKey.read(priv_pem)
+ pub = OpenSSL::PKey.read(pub_pem)
+ rescue OpenSSL::PKey::PKeyError
+ # OpenSSL < 1.1.1
+ pend "Ed25519 is not implemented"
+ end
+ assert_instance_of OpenSSL::PKey::PKey, priv
+ assert_instance_of OpenSSL::PKey::PKey, pub
+ assert_equal priv_pem, priv.private_to_pem
+ assert_equal pub_pem, priv.public_to_pem
+ assert_equal pub_pem, pub.public_to_pem
+
+ sig = [<<~EOF.gsub(/[^0-9a-f]/, "")].pack("H*")
+ 92a009a9f0d4cab8720e820b5f642540
+ a2b27b5416503f8fb3762223ebdb69da
+ 085ac1e43e15996e458f3613d0f11d8c
+ 387b2eaeb4302aeeb00d291612bb0c00
+ EOF
+ data = ["72"].pack("H*")
+ assert_equal sig, priv.sign(nil, data)
+ assert_equal true, priv.verify(nil, sig, data)
+ assert_equal true, pub.verify(nil, sig, data)
+ assert_equal false, pub.verify(nil, sig, data.succ)
+
+ # PureEdDSA wants nil as the message digest
+ assert_raise(OpenSSL::PKey::PKeyError) { priv.sign("SHA512", data) }
+ assert_raise(OpenSSL::PKey::PKeyError) { pub.verify("SHA512", sig, data) }
+
+ # Ed25519 pkey type does not support key derivation
+ assert_raise(OpenSSL::PKey::PKeyError) { priv.derive(pub) }
+ end
+
+ def test_x25519
+ # Test vector from RFC 7748 Section 6.1
+ alice_pem = <<~EOF
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VuBCIEIHcHbQpzGKV9PBbBclGyZkXfTC+H68CZKrF3+6UduSwq
+ -----END PRIVATE KEY-----
+ EOF
+ bob_pem = <<~EOF
+ -----BEGIN PUBLIC KEY-----
+ MCowBQYDK2VuAyEA3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08=
+ -----END PUBLIC KEY-----
+ EOF
+ shared_secret = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
+ begin
+ alice = OpenSSL::PKey.read(alice_pem)
+ bob = OpenSSL::PKey.read(bob_pem)
+ rescue OpenSSL::PKey::PKeyError
+ # OpenSSL < 1.1.0
+ pend "X25519 is not implemented"
+ end
+ assert_instance_of OpenSSL::PKey::PKey, alice
+ assert_equal alice_pem, alice.private_to_pem
+ assert_equal bob_pem, bob.public_to_pem
+ assert_equal [shared_secret].pack("H*"), alice.derive(bob)
+ end
end
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
index 4a05626a..9efc3ba6 100644
--- a/test/openssl/test_pkey_dh.rb
+++ b/test/openssl/test_pkey_dh.rb
@@ -18,6 +18,19 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
end
+ def test_derive_key
+ dh1 = Fixtures.pkey("dh1024").generate_key!
+ dh2 = Fixtures.pkey("dh1024").generate_key!
+ dh1_pub = OpenSSL::PKey.read(dh1.public_to_der)
+ dh2_pub = OpenSSL::PKey.read(dh2.public_to_der)
+ z = dh1.g.mod_exp(dh1.priv_key, dh1.p).mod_exp(dh2.priv_key, dh1.p).to_s(2)
+ assert_equal z, dh1.derive(dh2_pub)
+ assert_equal z, dh2.derive(dh1_pub)
+
+ assert_equal z, dh1.compute_key(dh2.pub_key)
+ assert_equal z, dh2.compute_key(dh1.pub_key)
+ end
+
def test_DHparams
dh1024 = Fixtures.pkey("dh1024")
asn1 = OpenSSL::ASN1::Sequence([
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
index a0e6a23f..95d4338a 100644
--- a/test/openssl/test_pkey_ec.rb
+++ b/test/openssl/test_pkey_ec.rb
@@ -93,6 +93,22 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
assert_equal false, p256.verify("SHA256", signature1, data)
end
+ def test_derive_key
+ # NIST CAVP, KAS_ECC_CDH_PrimitiveTest.txt, P-256 COUNT = 0
+ qCAVSx = "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287"
+ qCAVSy = "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"
+ dIUT = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"
+ zIUT = "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b"
+ a = OpenSSL::PKey::EC.new("prime256v1")
+ a.private_key = OpenSSL::BN.new(dIUT, 16)
+ b = OpenSSL::PKey::EC.new("prime256v1")
+ uncompressed = OpenSSL::BN.new("04" + qCAVSx + qCAVSy, 16)
+ b.public_key = OpenSSL::PKey::EC::Point.new(b.group, uncompressed)
+ assert_equal [zIUT].pack("H*"), a.derive(b)
+
+ assert_equal a.derive(b), a.dh_compute_key(b.public_key)
+ end
+
def test_dsa_sign_verify
data1 = "foo"
data2 = "bar"