Skip to content

Commit

Permalink
Merge pull request #804 from joshcooper/ed25519_req
Browse files Browse the repository at this point in the history
Support signing requests and CRLs using ED25519
  • Loading branch information
rhenium authored Nov 22, 2024
2 parents 6701d5e + b62375b commit 0759018
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 31 deletions.
6 changes: 5 additions & 1 deletion ext/openssl/ossl_x509crl.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,11 @@ ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest)

GetX509CRL(self, crl);
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_CRL_sign(crl, pkey, md)) {
ossl_raise(eX509CRLError, NULL);
}
Expand Down
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
13 changes: 4 additions & 9 deletions test/openssl/test_pkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ def test_hmac_sign_verify
def test_ed25519
# Ed25519 is not FIPS-approved.
omit_on_fips
# See EVP_PKEY_sign in Changelog for 3.7.0: https://github.com/libressl/portable/blob/master/ChangeLog
omit "Ed25519 not supported" unless openssl?(1, 1, 1) || libressl?(3, 7, 0)

# Test vector from RFC 8032 Section 7.1 TEST 2
priv_pem = <<~EOF
Expand All @@ -102,15 +104,8 @@ def test_ed25519
MCowBQYDK2VwAyEAPUAXw+hDiVqStwqnTRt+vJyYLM8uxJaMwM1V8Sr0Zgw=
-----END PUBLIC KEY-----
EOF
begin
priv = OpenSSL::PKey.read(priv_pem)
pub = OpenSSL::PKey.read(pub_pem)
rescue OpenSSL::PKey::PKeyError => e
# OpenSSL < 1.1.1
pend "Ed25519 is not implemented" unless openssl?(1, 1, 1)

raise e
end
priv = OpenSSL::PKey.read(priv_pem)
pub = OpenSSL::PKey.read(pub_pem)
assert_instance_of OpenSSL::PKey::PKey, priv
assert_instance_of OpenSSL::PKey::PKey, pub
assert_equal priv_pem, priv.private_to_pem
Expand Down
17 changes: 2 additions & 15 deletions test/openssl/test_x509cert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -292,24 +292,11 @@ def test_sign_and_verify_dsa_md5
end

def test_sign_and_verify_ed25519
# See test_ed25519 in test_pkey.rb

# Ed25519 is not FIPS-approved.
omit_on_fips

begin
ed25519 = OpenSSL::PKey::generate_key("ED25519")
rescue OpenSSL::PKey::PKeyError => e
# OpenSSL < 1.1.1
#
pend "Ed25519 is not implemented" unless openssl?(1, 1, 1)

raise e
end

# See ASN1_item_sign_ctx in ChangeLog for 3.8.1: https://github.com/libressl/portable/blob/master/ChangeLog
pend 'ASN1 signing with Ed25519 not yet working' unless openssl? or libressl?(3, 8, 1)

omit "Ed25519 not supported" unless openssl?(1, 1, 1) || libressl?(3, 8, 1)
ed25519 = OpenSSL::PKey::generate_key("ED25519")
cert = issue_cert(@ca, ed25519, 1, [], nil, nil, digest: nil)
assert_equal(true, cert.verify(ed25519))
end
Expand Down
17 changes: 17 additions & 0 deletions test/openssl/test_x509crl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,23 @@ def test_sign_and_verify
assert_equal(false, crl.verify(@dsa512))
end

def test_sign_and_verify_ed25519
# Ed25519 is not FIPS-approved.
omit_on_fips
# See ASN1_item_sign_ctx in ChangeLog for 3.8.1: https://github.com/libressl/portable/blob/master/ChangeLog
omit "Ed25519 not supported" unless openssl?(1, 1, 1) || libressl?(3, 8, 1)
ed25519 = OpenSSL::PKey::generate_key("ED25519")
cert = issue_cert(@ca, ed25519, 1, [], nil, nil, digest: nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, [],
cert, ed25519, nil)
assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) })
assert_equal(false, crl_error_returns_false { crl.verify(@rsa2048) })
assert_equal(false, crl.verify(OpenSSL::PKey::generate_key("ED25519")))
assert_equal(true, crl.verify(ed25519))
crl.version = 0
assert_equal(false, crl.verify(ed25519))
end

def test_revoked_to_der
# revokedCertificates SEQUENCE OF SEQUENCE {
# userCertificate CertificateSerialNumber,
Expand Down
25 changes: 20 additions & 5 deletions test/openssl/test_x509req.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ 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.public_to_der, req.public_key.public_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.public_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.public_to_der, req.public_key.public_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.public_to_der)
end

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

def test_sign_and_verify_ed25519
# Ed25519 is not FIPS-approved.
omit_on_fips
# See ASN1_item_sign_ctx in ChangeLog for 3.8.1: https://github.com/libressl/portable/blob/master/ChangeLog
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 0759018

Please sign in to comment.