Skip to content

Commit c85f7a1

Browse files
committed
Allow passing priv and pub parameters when creating EC pkey
1 parent e76f3e8 commit c85f7a1

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
@@ -267,12 +267,52 @@ def test_from_parameters_with_invalid_alg
267267
assert_equal e.message, '"ASR" is not a supported algorithm'
268268
end
269269

270-
def test_ec_from_parameters_with_minimal_data
270+
def test_ec_from_parameters_pub_given_as_string
271271
source = OpenSSL::PKey::EC.generate("prime256v1")
272+
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name,
273+
pub: source.public_key.to_bn.to_s(2) })
274+
assert_instance_of OpenSSL::PKey::EC, new_key
275+
assert_equal source.group.curve_name, new_key.group.curve_name
276+
assert_equal source.public_key, new_key.public_key
277+
assert_equal nil, new_key.private_key
278+
end
272279

273-
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name })
280+
def test_ec_from_parameters_priv_given_as_bn
281+
source = OpenSSL::PKey::EC.generate("prime256v1")
282+
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name,
283+
priv: source.private_key.to_bn })
274284
assert_instance_of OpenSSL::PKey::EC, new_key
275285
assert_equal source.group.curve_name, new_key.group.curve_name
286+
assert_equal source.private_key, new_key.private_key
287+
assert_equal nil, new_key.public_key
288+
end
289+
290+
def test_ec_from_parameters_priv_given_as_integer
291+
source = OpenSSL::PKey::EC.generate("prime256v1")
292+
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name,
293+
priv: source.private_key.to_i })
294+
assert_instance_of OpenSSL::PKey::EC, new_key
295+
assert_equal source.group.curve_name, new_key.group.curve_name
296+
assert_equal source.private_key, new_key.private_key
297+
assert_equal nil, new_key.public_key
298+
end
299+
300+
def test_ec_from_parameters_priv_and_pub_given_for_different_curves
301+
["prime256v1", "secp256k1", "secp384r1", "secp521r1"].each do |curve|
302+
source = OpenSSL::PKey::EC.generate(curve)
303+
new_key = OpenSSL::PKey.from_parameters("EC", { group: source.group.curve_name,
304+
pub: source.public_key.to_bn.to_s(2),
305+
priv: source.private_key.to_i })
306+
assert_instance_of OpenSSL::PKey::EC, new_key
307+
assert_equal source.group.curve_name, new_key.group.curve_name
308+
assert_equal source.private_key, new_key.private_key
309+
assert_equal source.public_key, new_key.public_key
310+
end
311+
end
312+
313+
def test_ec_from_parameters_pub_given_as_integer
314+
e = assert_raise(TypeError) { OpenSSL::PKey.from_parameters("EC", { group: "prime256v1", pub: 12345 }) }
315+
assert_equal "no implicit conversion of Integer into String", e.message
276316
end
277317
else
278318
def test_from_parameter_raises_on_pre_3_openssl

0 commit comments

Comments
 (0)