Skip to content

Commit

Permalink
Add match method to PKEY that wraps EVP_PKEY_cmp.
Browse files Browse the repository at this point in the history
  • Loading branch information
cwjenkins committed Jul 5, 2020
1 parent b362c0a commit ba39137
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 0 deletions.
23 changes: 23 additions & 0 deletions ext/openssl/ossl_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,28 @@ ossl_pkey_check_public_key(const EVP_PKEY *pkey)
ossl_raise(ePKeyError, "public key missing");
}

static VALUE
ossl_pkey_match(VALUE self, VALUE other)
{
int ret;
EVP_PKEY *selfPKey;
EVP_PKEY *otherPKey;

GetPKey(self, selfPKey);
GetPKey(other, otherPKey);

ret = EVP_PKEY_cmp(selfPKey, otherPKey);

if (ret == -1)
ossl_raise(rb_eTypeError, "cannot match different PKey types");
else if (ret == -2)
ossl_raise(rb_eNotImpError, "the pkey needs to implement param_cmp or pub_cmp");
else if (ret == 1)
return Qtrue;

return Qfalse;
}

EVP_PKEY *
GetPKeyPtr(VALUE obj)
{
Expand Down Expand Up @@ -1031,6 +1053,7 @@ Init_ossl_pkey(void)
rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0);
rb_define_method(cPKey, "match?", ossl_pkey_match, 1);

rb_define_method(cPKey, "sign", ossl_pkey_sign, 2);
rb_define_method(cPKey, "verify", ossl_pkey_verify, 3);
Expand Down
5 changes: 5 additions & 0 deletions test/openssl/fixtures/pkey/secp224r1.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MGgCAQEEHLAQrbqRZFCx5DxdMGsWXNACy00nC2JZJGx8I3qgBwYFK4EEACGhPAM6
AAQdEWf8Z6Z6yujxcdJBbSfYBaS/sG+cx77Aw+7CgSt7tEI3RSwDNpxFC1jAz5Jk
AZrdK0jO1I1XOw==
-----END EC PRIVATE KEY-----
18 changes: 18 additions & 0 deletions test/openssl/test_pkey_dh.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,24 @@ def test_dup
assert_equal dh2.g, dh.g
end

def test_match?
key1 = Fixtures.pkey("dh1024")
key2 = Fixtures.pkey("dh1024")

key3 = Fixtures.pkey("dh-1")

assert(key1.match?(key2))
assert(key1.public_key.match?(key2))
assert(key2.match?(key1))
assert(key2.public_key.match?(key1))

assert(!key1.match?(key3))

assert_raise(TypeError) do
key1.match?("DH Key")
end
end

def test_marshal
dh = Fixtures.pkey("dh1024")
deserialized = Marshal.load(Marshal.dump(dh))
Expand Down
18 changes: 18 additions & 0 deletions test/openssl/test_pkey_dsa.rb
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,24 @@ def test_dup
assert_not_equal key.params, key2.params
end

def test_match?
key1 = Fixtures.pkey("dsa256")
key2 = Fixtures.pkey("dsa256")

key3 = Fixtures.pkey("dsa512")

assert(key1.match?(key2))
assert(key1.public_key.match?(key2))
assert(key2.match?(key1))
assert(key2.public_key.match?(key1))

assert(!key1.match?(key3))

assert_raise(TypeError) do
key1.match?("DSA Key")
end
end

def test_marshal
key = Fixtures.pkey("dsa1024")
deserialized = Marshal.load(Marshal.dump(key))
Expand Down
18 changes: 18 additions & 0 deletions test/openssl/test_pkey_ec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ def test_check_key
assert_raise(OpenSSL::PKey::ECError) { key2.check_key }
end

def test_match?
key1 = Fixtures.pkey("p256")
key2 = Fixtures.pkey("p256")

key3 = Fixtures.pkey("secp224r1")

assert(key1.match?(key2))
# assert(key1.public_key.match?(key2)) EC::Point isn't wrapped in EVP
assert(key2.match?(key1))
# assert(key2.public_key.match?(key1)) EC::Point isn't wrapped in EVP

assert(!key1.match?(key3))

assert_raise(TypeError) do
key1.match?("EC Key")
end
end

def test_sign_verify
p256 = Fixtures.pkey("p256")
data = "Sign me!"
Expand Down
18 changes: 18 additions & 0 deletions test/openssl/test_pkey_rsa.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ def test_private
assert(!key6.private?)
end

def test_match?
key1 = Fixtures.pkey("rsa1024")
key2 = Fixtures.pkey("rsa1024")

key3 = Fixtures.pkey("rsa2048")

assert(key1.match?(key2))
assert(key1.public_key.match?(key2))
assert(key2.match?(key1))
assert(key2.public_key.match?(key1))

assert(!key1.match?(key3))

assert_raise(TypeError) do
key1.match?("RSA Key")
end
end

def test_new
key = OpenSSL::PKey::RSA.new 512
pem = key.public_key.to_pem
Expand Down

0 comments on commit ba39137

Please sign in to comment.