Skip to content

Commit d960903

Browse files
committed
Support signing requests using Ed25519
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.
1 parent f1db5c8 commit d960903

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

ext/openssl/ossl_x509req.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,11 @@ ossl_x509req_sign(VALUE self, VALUE key, VALUE digest)
312312

313313
GetX509Req(self, req);
314314
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
315-
md = ossl_evp_get_digestbyname(digest);
315+
if (NIL_P(digest)) {
316+
md = NULL; /* needed for some key types, e.g. Ed25519 */
317+
} else {
318+
md = ossl_evp_get_digestbyname(digest);
319+
}
316320
if (!X509_REQ_sign(req, pkey, md)) {
317321
ossl_raise(eX509ReqError, NULL);
318322
}

test/openssl/test_x509req.rb

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@ def issue_csr(ver, dn, key, digest)
1717
req = OpenSSL::X509::Request.new
1818
req.version = ver
1919
req.subject = dn
20-
req.public_key = key.public_key
20+
req.public_key = key
2121
req.sign(key, digest)
2222
req
2323
end
2424

2525
def test_public_key
2626
req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
27-
assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
27+
assert_equal(@rsa1024.public_to_der, req.public_key.public_to_der)
2828
req = OpenSSL::X509::Request.new(req.to_der)
29-
assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
29+
assert_equal(@rsa1024.public_to_der, req.public_key.public_to_der)
3030

3131
req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA256'))
32-
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
32+
assert_equal(@dsa512.public_to_der, req.public_key.public_to_der)
3333
req = OpenSSL::X509::Request.new(req.to_der)
34-
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
34+
assert_equal(@dsa512.public_to_der, req.public_key.public_to_der)
3535
end
3636

3737
def test_version
@@ -132,6 +132,21 @@ def test_sign_and_verify_dsa_md5
132132
issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('MD5')) }
133133
end
134134

135+
def test_sign_and_verify_ed25519
136+
# Ed25519 is not FIPS-approved.
137+
omit_on_fips
138+
# See ASN1_item_sign_ctx in ChangeLog for 3.8.1: https://github.com/libressl/portable/blob/master/ChangeLog
139+
omit "Ed25519 not supported" unless openssl?(1, 1, 1) || libressl?(3, 8, 1)
140+
ed25519 = OpenSSL::PKey::generate_key("ED25519")
141+
req = issue_csr(0, @dn, ed25519, nil)
142+
assert_equal(false, request_error_returns_false { req.verify(@rsa1024) })
143+
assert_equal(false, request_error_returns_false { req.verify(@rsa2048) })
144+
assert_equal(false, req.verify(OpenSSL::PKey::generate_key("ED25519")))
145+
assert_equal(true, req.verify(ed25519))
146+
req.public_key = @rsa1024.public_key
147+
assert_equal(false, req.verify(ed25519))
148+
end
149+
135150
def test_dup
136151
req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
137152
assert_equal(req.to_der, req.dup.to_der)

0 commit comments

Comments
 (0)