Skip to content

Commit 797e9f8

Browse files
committed
pkey/dh, pkey/ec: use EVP_PKEY_check() family
Use EVP_PKEY_param_check() instead of DH_check() if available. Also, use EVP_PKEY_public_check() instead of EC_KEY_check_key(). EVP_PKEY_*check() is part of the EVP API and is meant to replace those low-level functions. They were added by OpenSSL 1.1.1. It is currently not provided by LibreSSL.
1 parent 48a6c39 commit 797e9f8

File tree

4 files changed

+61
-8
lines changed

4 files changed

+61
-8
lines changed

ext/openssl/extconf.rb

+3
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ def find_openssl_library
165165
have_func("EVP_PBE_scrypt")
166166
have_func("SSL_CTX_set_post_handshake_auth")
167167

168+
# added in 1.1.1
169+
have_func("EVP_PKEY_check")
170+
168171
Logging::message "=== Checking done. ===\n"
169172

170173
create_header

ext/openssl/ossl_pkey_dh.c

+23-4
Original file line numberDiff line numberDiff line change
@@ -273,19 +273,38 @@ ossl_dh_get_params(VALUE self)
273273
* Validates the Diffie-Hellman parameters associated with this instance.
274274
* It checks whether a safe prime and a suitable generator are used. If this
275275
* is not the case, +false+ is returned.
276+
*
277+
* See also the man page EVP_PKEY_param_check(3).
276278
*/
277279
static VALUE
278280
ossl_dh_check_params(VALUE self)
279281
{
282+
int ret;
283+
#ifdef HAVE_EVP_PKEY_CHECK
284+
EVP_PKEY *pkey;
285+
EVP_PKEY_CTX *pctx;
286+
287+
GetPKey(self, pkey);
288+
pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
289+
if (!pctx)
290+
ossl_raise(eDHError, "EVP_PKEY_CTX_new");
291+
ret = EVP_PKEY_param_check(pctx);
292+
EVP_PKEY_CTX_free(pctx);
293+
#else
280294
DH *dh;
281295
int codes;
282296

283297
GetDH(self, dh);
284-
if (!DH_check(dh, &codes)) {
285-
return Qfalse;
286-
}
298+
ret = DH_check(dh, &codes) == 1 && codes == 0;
299+
#endif
287300

288-
return codes == 0 ? Qtrue : Qfalse;
301+
if (ret == 1)
302+
return Qtrue;
303+
else {
304+
/* DH_check_ex() will put error entry on failure */
305+
ossl_clear_error();
306+
return Qfalse;
307+
}
289308
}
290309

291310
/*

ext/openssl/ossl_pkey_ec.c

+19-4
Original file line numberDiff line numberDiff line change
@@ -438,20 +438,35 @@ static VALUE ossl_ec_key_generate_key(VALUE self)
438438
}
439439

440440
/*
441-
* call-seq:
442-
* key.check_key => true
441+
* call-seq:
442+
* key.check_key => true
443443
*
444-
* Raises an exception if the key is invalid.
444+
* Raises an exception if the key is invalid.
445445
*
446-
* See the OpenSSL documentation for EC_KEY_check_key()
446+
* See also the man page EVP_PKEY_public_check(3).
447447
*/
448448
static VALUE ossl_ec_key_check_key(VALUE self)
449449
{
450+
#ifdef HAVE_EVP_PKEY_CHECK
451+
EVP_PKEY *pkey;
452+
EVP_PKEY_CTX *pctx;
453+
int ret;
454+
455+
GetPKey(self, pkey);
456+
pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
457+
if (!pctx)
458+
ossl_raise(eDHError, "EVP_PKEY_CTX_new");
459+
ret = EVP_PKEY_public_check(pctx);
460+
EVP_PKEY_CTX_free(pctx);
461+
if (ret != 1)
462+
ossl_raise(eECError, "EVP_PKEY_public_check");
463+
#else
450464
EC_KEY *ec;
451465

452466
GetEC(self, ec);
453467
if (EC_KEY_check_key(ec) != 1)
454468
ossl_raise(eECError, "EC_KEY_check_key");
469+
#endif
455470

456471
return Qtrue;
457472
}

test/openssl/test_pkey_dh.rb

+16
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,22 @@ def test_key_exchange
8686
assert_equal(dh.compute_key(dh2.pub_key), dh2.compute_key(dh.pub_key))
8787
end
8888

89+
def test_params_ok?
90+
dh0 = Fixtures.pkey("dh1024")
91+
92+
dh1 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([
93+
OpenSSL::ASN1::Integer(dh0.p),
94+
OpenSSL::ASN1::Integer(dh0.g)
95+
]))
96+
assert_equal(true, dh1.params_ok?)
97+
98+
dh2 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([
99+
OpenSSL::ASN1::Integer(dh0.p + 1),
100+
OpenSSL::ASN1::Integer(dh0.g)
101+
]))
102+
assert_equal(false, dh2.params_ok?)
103+
end
104+
89105
def test_dup
90106
dh = Fixtures.pkey("dh1024")
91107
dh2 = dh.dup

0 commit comments

Comments
 (0)