Skip to content

Commit

Permalink
Support signing requests using Ed25519
Browse files Browse the repository at this point in the history
Allow requests to be signed using Ed25519 private keys by passing a nil digest.
This is similar to commit b0fc100 when signing certs.

Calling PKey#public_key is deprecated and does not work for Ed25519. The same
can be accomplished by passing the private key.
  • Loading branch information
joshcooper committed Nov 6, 2024
1 parent b4f8aab commit ade53f2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
6 changes: 5 additions & 1 deletion ext/openssl/ossl_x509req.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,11 @@ ossl_x509req_sign(VALUE self, VALUE key, VALUE digest)

GetX509Req(self, req);
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
md = ossl_evp_get_digestbyname(digest);
if (NIL_P(digest)) {
md = NULL; /* needed for some key types, e.g. Ed25519 */
} else {
md = ossl_evp_get_digestbyname(digest);
}
if (!X509_REQ_sign(req, pkey, md)) {
ossl_raise(eX509ReqError, NULL);
}
Expand Down
24 changes: 19 additions & 5 deletions test/openssl/test_x509req.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,26 @@ def setup
@dn = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou")
end


def issue_csr(ver, dn, key, digest)
req = OpenSSL::X509::Request.new
req.version = ver
req.subject = dn
req.public_key = key.public_key
req.public_key = key
req.sign(key, digest)
req
end

def test_public_key
req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
assert_equal(@rsa1024.to_der, req.public_key.to_der)
req = OpenSSL::X509::Request.new(req.to_der)
assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
assert_equal(@rsa1024.public_to_der, req.public_key.to_der)

req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA256'))
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
assert_equal(@dsa512.to_der, req.public_key.to_der)
req = OpenSSL::X509::Request.new(req.to_der)
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
assert_equal(@dsa512.public_to_der, req.public_key.to_der)
end

def test_version
Expand Down Expand Up @@ -132,6 +133,19 @@ def test_sign_and_verify_dsa_md5
issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('MD5')) }
end

def test_sign_and_verify_ed25519
omit_on_fips
omit "Ed25519 not supported" unless openssl?(1, 1, 1) || libressl?(3, 8, 1)
ed25519 = OpenSSL::PKey::generate_key("ED25519")
req = issue_csr(0, @dn, ed25519, nil)
assert_equal(false, request_error_returns_false { req.verify(@rsa1024) })
assert_equal(false, request_error_returns_false { req.verify(@rsa2048) })
assert_equal(false, req.verify(OpenSSL::PKey::generate_key("ED25519")))
assert_equal(true, req.verify(ed25519))
req.public_key = @rsa1024.public_key
assert_equal(false, req.verify(ed25519))
end

def test_dup
req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
assert_equal(req.to_der, req.dup.to_der)
Expand Down

0 comments on commit ade53f2

Please sign in to comment.