Skip to content

tls: add Ed25519 certificate support#9452

Open
nathannewyen wants to merge 2 commits into
square:masterfrom
nathannewyen:master
Open

tls: add Ed25519 certificate support#9452
nathannewyen wants to merge 2 commits into
square:masterfrom
nathannewyen:master

Conversation

@nathannewyen
Copy link
Copy Markdown

@nathannewyen nathannewyen commented May 24, 2026

Fixes #9437 - Ed25519 client certificates not being sent in mTLS setups.

Added Ed25519 support to okhttp-tls: new ed25519() builder method, proper key detection in decode(), and the Ed25519 OID in the DER layer.

)
}

signedByKeyPair.private.algorithm == "Ed25519" || signedByKeyPair.private.algorithm == "EdDSA" -> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given differing providers, I'm worried about case sensitivity, can you audit how it's represented in providers, and maybe make it case insensitive, if it's not guaranteed by a spec.

private fun generateKeyPair(): KeyPair =
KeyPairGenerator.getInstance(keyAlgorithm).run {
initialize(keySize, SecureRandom())
if (keySize > 0) initialize(keySize, SecureRandom())
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worth a comment since this affects other code paths.


@Test
fun ed25519() {
platform.assumeNotAndroid()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is just in the tests, but if called by an app, we should have a useful error message.

Something like

Ed25519 requires JDK 15+ / a provider that supports it

)
}

signedByKeyPair.private.algorithm == "Ed25519" || signedByKeyPair.private.algorithm == "EdDSA" -> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

signedByKeyPair.private.algorithm == "EdDSA"

Is this check complete? or are there sub algorithms?

@yschimke
Copy link
Copy Markdown
Collaborator

Failures

HeldCertificateTest > ed25519() FAILED
java.lang.NullPointerException: null cannot be cast to non-null type okio.ByteString
at okhttp3.tls.internal.der.Adapters$usingTypeHint$1.toDer(Adapters.kt:450)
at okhttp3.tls.internal.der.Adapters$sequence$codec$1.encode$lambda$1(Adapters.kt:383)
at okhttp3.tls.internal.der.DerWriter.withTypeHint(DerWriter.kt:109)
at okhttp3.tls.internal.der.Adapters$sequence$codec$1.encode(Adapters.kt:380)
at okhttp3.tls.internal.der.BasicDerAdapter.toDer$lambda$0(BasicDerAdapter.kt:81)
at okhttp3.tls.internal.der.DerWriter.write(DerWriter.kt:64)
at okhttp3.tls.internal.der.BasicDerAdapter.toDer(BasicDerAdapter.kt:80)
at okhttp3.tls.internal.der.Adapters$sequence$codec$1.encode$lambda$1(Adapters.kt:383)
at okhttp3.tls.internal.der.DerWriter.withTypeHint(DerWriter.kt:109)
at okhttp3.tls.internal.der.Adapters$sequence$codec$1.encode(Adapters.kt:380)
at okhttp3.tls.internal.der.BasicDerAdapter.toDer$lambda$0(BasicDerAdapter.kt:81)
at okhttp3.tls.internal.der.DerWriter.write(DerWriter.kt:64)
at okhttp3.tls.internal.der.BasicDerAdapter.toDer(BasicDerAdapter.kt:80)
at okhttp3.tls.internal.der.DerAdapter.toDer(DerAdapter.kt:61)
at okhttp3.tls.HeldCertificate$Builder.build(HeldCertificate.kt:401)
at okhttp3.tls.HeldCertificateTest.ed25519(HeldCertificateTest.kt:273)

HeldCertificateTest > ed25519SignedByEcdsa() FAILED
org.opentest4j.AssertionFailedError: expected:<"Ed[25519]"> but was:<"Ed[DSA]">
at app//okhttp3.tls.HeldCertificateTest.ed25519SignedByEcdsa(HeldCertificateTest.kt:312)

@nathannewyen
Copy link
Copy Markdown
Author

Thanks for running the tests! Fixed both issues — the NPE was caused by usingTypeHint.toDer not handling absent parameters (null value with no registered adapter for the Ed25519 OID). Added a null guard so it skips writing rather than crashing. Also loosened the algorithm name assertions to accept both "Ed25519" and "EdDSA" since different JVMs report different strings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ed25519 client certificate is not sent to server in mtls set up

2 participants