Skip to content

Commit 0759018

Browse files
authored
Merge pull request #804 from joshcooper/ed25519_req
Support signing requests and CRLs using ED25519
2 parents 6701d5e + b62375b commit 0759018

File tree

6 files changed

+53
-31
lines changed

6 files changed

+53
-31
lines changed

ext/openssl/ossl_x509crl.c

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

351351
GetX509CRL(self, crl);
352352
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
353-
md = ossl_evp_get_digestbyname(digest);
353+
if (NIL_P(digest)) {
354+
md = NULL; /* needed for some key types, e.g. Ed25519 */
355+
} else {
356+
md = ossl_evp_get_digestbyname(digest);
357+
}
354358
if (!X509_CRL_sign(crl, pkey, md)) {
355359
ossl_raise(eX509CRLError, NULL);
356360
}

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_pkey.rb

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ def test_hmac_sign_verify
9090
def test_ed25519
9191
# Ed25519 is not FIPS-approved.
9292
omit_on_fips
93+
# See EVP_PKEY_sign in Changelog for 3.7.0: https://github.com/libressl/portable/blob/master/ChangeLog
94+
omit "Ed25519 not supported" unless openssl?(1, 1, 1) || libressl?(3, 7, 0)
9395

9496
# Test vector from RFC 8032 Section 7.1 TEST 2
9597
priv_pem = <<~EOF
@@ -102,15 +104,8 @@ def test_ed25519
102104
MCowBQYDK2VwAyEAPUAXw+hDiVqStwqnTRt+vJyYLM8uxJaMwM1V8Sr0Zgw=
103105
-----END PUBLIC KEY-----
104106
EOF
105-
begin
106-
priv = OpenSSL::PKey.read(priv_pem)
107-
pub = OpenSSL::PKey.read(pub_pem)
108-
rescue OpenSSL::PKey::PKeyError => e
109-
# OpenSSL < 1.1.1
110-
pend "Ed25519 is not implemented" unless openssl?(1, 1, 1)
111-
112-
raise e
113-
end
107+
priv = OpenSSL::PKey.read(priv_pem)
108+
pub = OpenSSL::PKey.read(pub_pem)
114109
assert_instance_of OpenSSL::PKey::PKey, priv
115110
assert_instance_of OpenSSL::PKey::PKey, pub
116111
assert_equal priv_pem, priv.private_to_pem

test/openssl/test_x509cert.rb

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -292,24 +292,11 @@ def test_sign_and_verify_dsa_md5
292292
end
293293

294294
def test_sign_and_verify_ed25519
295-
# See test_ed25519 in test_pkey.rb
296-
297295
# Ed25519 is not FIPS-approved.
298296
omit_on_fips
299-
300-
begin
301-
ed25519 = OpenSSL::PKey::generate_key("ED25519")
302-
rescue OpenSSL::PKey::PKeyError => e
303-
# OpenSSL < 1.1.1
304-
#
305-
pend "Ed25519 is not implemented" unless openssl?(1, 1, 1)
306-
307-
raise e
308-
end
309-
310297
# See ASN1_item_sign_ctx in ChangeLog for 3.8.1: https://github.com/libressl/portable/blob/master/ChangeLog
311-
pend 'ASN1 signing with Ed25519 not yet working' unless openssl? or libressl?(3, 8, 1)
312-
298+
omit "Ed25519 not supported" unless openssl?(1, 1, 1) || libressl?(3, 8, 1)
299+
ed25519 = OpenSSL::PKey::generate_key("ED25519")
313300
cert = issue_cert(@ca, ed25519, 1, [], nil, nil, digest: nil)
314301
assert_equal(true, cert.verify(ed25519))
315302
end

test/openssl/test_x509crl.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,23 @@ def test_sign_and_verify
204204
assert_equal(false, crl.verify(@dsa512))
205205
end
206206

207+
def test_sign_and_verify_ed25519
208+
# Ed25519 is not FIPS-approved.
209+
omit_on_fips
210+
# See ASN1_item_sign_ctx in ChangeLog for 3.8.1: https://github.com/libressl/portable/blob/master/ChangeLog
211+
omit "Ed25519 not supported" unless openssl?(1, 1, 1) || libressl?(3, 8, 1)
212+
ed25519 = OpenSSL::PKey::generate_key("ED25519")
213+
cert = issue_cert(@ca, ed25519, 1, [], nil, nil, digest: nil)
214+
crl = issue_crl([], 1, Time.now, Time.now+1600, [],
215+
cert, ed25519, nil)
216+
assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) })
217+
assert_equal(false, crl_error_returns_false { crl.verify(@rsa2048) })
218+
assert_equal(false, crl.verify(OpenSSL::PKey::generate_key("ED25519")))
219+
assert_equal(true, crl.verify(ed25519))
220+
crl.version = 0
221+
assert_equal(false, crl.verify(ed25519))
222+
end
223+
207224
def test_revoked_to_der
208225
# revokedCertificates SEQUENCE OF SEQUENCE {
209226
# userCertificate CertificateSerialNumber,

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)