Skip to content

Commit 1588b2c

Browse files
committed
Allow passing priv and pub parameters when creating EC pkey
1 parent 61052b4 commit 1588b2c

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

ext/openssl/ossl_pkey.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,11 +439,27 @@ add_ec_parameters_to_builder(VALUE key, VALUE value, VALUE arg) {
439439

440440
const char * key_ptr = StringValueCStr(key);
441441

442-
if(strcmp(OSSL_PKEY_PARAM_GROUP_NAME, key_ptr) == 0)
443-
if(!OSSL_PARAM_BLD_push_utf8_string(params_builder, key_ptr, StringValueCStr(value), 0))
442+
if(strcmp(OSSL_PKEY_PARAM_GROUP_NAME, key_ptr) == 0) {
443+
StringValue(value);
444+
if(!OSSL_PARAM_BLD_push_utf8_string(params_builder, key_ptr, RSTRING_PTR(value), RSTRING_LENINT(value)))
444445
ossl_raise(ePKeyError, "OSSL_PARAM_BLD_push_utf8_string");
446+
return ST_CONTINUE;
447+
}
445448

446-
return ST_CONTINUE;
449+
if(strcmp(OSSL_PKEY_PARAM_PUB_KEY, key_ptr) == 0) {
450+
StringValue(value);
451+
if(!OSSL_PARAM_BLD_push_octet_string(params_builder, OSSL_PKEY_PARAM_PUB_KEY, RSTRING_PTR(value), RSTRING_LENINT(value)))
452+
ossl_raise(ePKeyError, "OSSL_PARAM_BLD_push_octet_string");
453+
return ST_CONTINUE;
454+
}
455+
456+
if(strcmp(OSSL_PKEY_PARAM_PRIV_KEY, key_ptr) == 0) {
457+
if(!OSSL_PARAM_BLD_push_BN(params_builder, OSSL_PKEY_PARAM_PRIV_KEY, GetBNPtr(value))) // unsigned integer, but presented as BN will work just fine
458+
ossl_raise(ePKeyError, "OSSL_PARAM_BLD_push_octet_string");
459+
return ST_CONTINUE;
460+
}
461+
462+
ossl_raise(ePKeyError, "Unsupported EC parameter \"%s\"", key_ptr);
447463
}
448464

449465
static int

test/openssl/test_pkey.rb

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,52 @@ def test_from_parameters_with_invalid_alg
262262
assert_equal e.message, '"ASR" is not a supported algorithm'
263263
end
264264

265-
def test_ec_from_parameters_with_minimal_data
265+
def test_ec_from_parameters_pub_given_as_string
266266
source = OpenSSL::PKey::EC.generate("prime256v1")
267+
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name,
268+
pub: source.public_key.to_bn.to_s(2) })
269+
assert_instance_of OpenSSL::PKey::EC, new_key
270+
assert_equal source.group.curve_name, new_key.group.curve_name
271+
assert_equal source.public_key, new_key.public_key
272+
assert_equal nil, new_key.private_key
273+
end
267274

268-
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name })
275+
def test_ec_from_parameters_priv_given_as_bn
276+
source = OpenSSL::PKey::EC.generate("prime256v1")
277+
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name,
278+
priv: source.private_key.to_bn })
269279
assert_instance_of OpenSSL::PKey::EC, new_key
270280
assert_equal source.group.curve_name, new_key.group.curve_name
281+
assert_equal source.private_key, new_key.private_key
282+
assert_equal nil, new_key.public_key
283+
end
284+
285+
def test_ec_from_parameters_priv_given_as_integer
286+
source = OpenSSL::PKey::EC.generate("prime256v1")
287+
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name,
288+
priv: source.private_key.to_i })
289+
assert_instance_of OpenSSL::PKey::EC, new_key
290+
assert_equal source.group.curve_name, new_key.group.curve_name
291+
assert_equal source.private_key, new_key.private_key
292+
assert_equal nil, new_key.public_key
293+
end
294+
295+
def test_ec_from_parameters_priv_and_pub_given_for_different_curves
296+
["prime256v1", "secp256k1", "secp384r1", "secp521r1"].each do |curve|
297+
source = OpenSSL::PKey::EC.generate(curve)
298+
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name,
299+
pub: source.public_key.to_bn.to_s(2),
300+
priv: source.private_key.to_i })
301+
assert_instance_of OpenSSL::PKey::EC, new_key
302+
assert_equal source.group.curve_name, new_key.group.curve_name
303+
assert_equal source.private_key, new_key.private_key
304+
assert_equal source.public_key, new_key.public_key
305+
end
306+
end
307+
308+
def test_ec_from_parameters_pub_given_as_integer
309+
e = assert_raise(TypeError) { OpenSSL::PKey.from_parameters("EC", { group: "prime256v1", pub: 12345 }) }
310+
assert_equal "no implicit conversion of Integer into String", e.message
271311
end
272312
else
273313
def test_from_parameter_raises_on_pre_3_openssl

0 commit comments

Comments
 (0)