aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2022-01-04 22:11:00 +0900
committerKazuki Yamaguchi <k@rhe.jp>2022-09-02 15:27:01 +0900
commit0105975a0b4a8ca6498bbeab95cc4e123e2faf98 (patch)
tree80dcb9dd377ff75418a2b154f096e14f29d51db6
parentbff4080091f1e468418b0a8625174f234922210c (diff)
downloadruby-openssl-ky/pkey-dsa-generate-fix-q.tar.gz
pkey/dsa: let PKey::DSA.generate choose appropriate q sizeky/pkey-dsa-generate-fix-q
DSA parameters generation via EVP_PKEY_paramgen() will not automatically adjust the size of q value but uses 224 bits by default unless specified explicitly. This behavior is different from the now-deprecated DSA_generate_parameters_ex(), which PKey::DSA.generate used to call. Fixes https://github.com/ruby/openssl/issues/483 Fixes: 1800a8d5ebaf ("pkey/dsa: use high level EVP interface to generate parameters and keys", 2020-05-17)
-rw-r--r--lib/openssl/pkey.rb8
-rw-r--r--test/openssl/test_pkey_dsa.rb19
2 files changed, 27 insertions, 0 deletions
diff --git a/lib/openssl/pkey.rb b/lib/openssl/pkey.rb
index c3e06290..d51f066b 100644
--- a/lib/openssl/pkey.rb
+++ b/lib/openssl/pkey.rb
@@ -167,8 +167,16 @@ module OpenSSL::PKey
# +size+::
# The desired key size in bits.
def generate(size, &blk)
+ # FIPS 186-4 specifies four (L,N) pairs: (1024,160), (2048,224),
+ # (2048,256), and (3072,256).
+ #
+ # q size is derived here with compatibility with
+ # DSA_generator_parameters_ex() which previous versions of ruby/openssl
+ # used to call.
+ qsize = size >= 2048 ? 256 : 160
dsaparams = OpenSSL::PKey.generate_parameters("DSA", {
"dsa_paramgen_bits" => size,
+ "dsa_paramgen_q_bits" => qsize,
}, &blk)
OpenSSL::PKey.generate_key(dsaparams)
end
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
index 726b7dbf..de6aa63e 100644
--- a/test/openssl/test_pkey_dsa.rb
+++ b/test/openssl/test_pkey_dsa.rb
@@ -28,6 +28,25 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
end
end
+ def test_generate
+ # DSA.generate used to call DSA_generate_parameters_ex(), which adjusts the
+ # size of q according to the size of p
+ key1024 = OpenSSL::PKey::DSA.generate(1024)
+ assert_predicate key1024, :private?
+ assert_equal 1024, key1024.p.num_bits
+ assert_equal 160, key1024.q.num_bits
+
+ key2048 = OpenSSL::PKey::DSA.generate(2048)
+ assert_equal 2048, key2048.p.num_bits
+ assert_equal 256, key2048.q.num_bits
+
+ if ENV["OSSL_TEST_ALL"] == "1" # slow
+ key3072 = OpenSSL::PKey::DSA.generate(3072)
+ assert_equal 3072, key3072.p.num_bits
+ assert_equal 256, key3072.q.num_bits
+ end
+ end
+
def test_sign_verify
dsa512 = Fixtures.pkey("dsa512")
data = "Sign me!"