Skip to content

Expose TLS signature algorithm and per-connection sigalg preferences#513

Open
lukevalenta wants to merge 2 commits into
cloudflare:masterfrom
lukevalenta:mldsa-signature-algorithm
Open

Expose TLS signature algorithm and per-connection sigalg preferences#513
lukevalenta wants to merge 2 commits into
cloudflare:masterfrom
lukevalenta:mldsa-signature-algorithm

Conversation

@lukevalenta

@lukevalenta lukevalenta commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Add bindings for inspecting the signature algorithm (incl. ML-DSA) negotiated on a TLS connection, and for setting the accepted signature algorithms per-connection.

Expose peer signature algorithm and post-quantum sig constants is net-new functionality to surface the negotiated signature algorithm. The ML-DSA constants use hardcoded IANA codepoints (rather than ffi::SSL_SIGN_ML_DSA_*) so the crate continues to compile against older BoringSSL versions. This has planned usage in a downstream consumer.

Expose per-connection verify algorithm preferences adds SslRef::set_verify_algorithm_prefs, the per-connection counterpart to the existing SslContextBuilder::set_verify_algorithm_prefs. This has planned usage in a downstream consumer.

Closes #511.

@lukevalenta lukevalenta force-pushed the mldsa-signature-algorithm branch from e5516cc to 015e6cc Compare June 24, 2026 15:23
Comment thread boring/src/ssl/mod.rs
Comment thread boring/src/ssl/mod.rs Outdated
Comment thread boring/src/ssl/mod.rs Outdated
@lukevalenta lukevalenta force-pushed the mldsa-signature-algorithm branch from 015e6cc to 7f0bf94 Compare June 24, 2026 15:59
Comment thread boring/src/ssl/mod.rs Outdated
Comment on lines +745 to +752
pub const ML_DSA_44: SslSignatureAlgorithm =
SslSignatureAlgorithm(ffi::SSL_SIGN_ML_DSA_44 as _);

pub const ML_DSA_65: SslSignatureAlgorithm =
SslSignatureAlgorithm(ffi::SSL_SIGN_ML_DSA_65 as _);

pub const ML_DSA_87: SslSignatureAlgorithm =
SslSignatureAlgorithm(ffi::SSL_SIGN_ML_DSA_87 as _);

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 creates some friction for downstream users who want a newer version of boring but are stuck on an older version of BoringSSL (e.g., because they have their own patch set they would need to rebase), then it will fail to compile.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What about hard-coding the code points instead of pulling them from BoringSSL? Then, once we think consumers are all on recent-enough BoringSSL versions, we could again pull them via ffi.

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 works!

Comment thread boring/src/ssl/mod.rs
Add Rust bindings for identifying the signature algorithm negotiated
during a TLS handshake, including the post-quantum ML-DSA signature
family. These are useful for inspecting which signature scheme each
side of a handshake used to authenticate itself.

SslSignatureAlgorithm:
  - ML_DSA_44 / ML_DSA_65 / ML_DSA_87 constants
  - name()    wraps SSL_get_signature_algorithm_name (TLS 1.3 form)
  - Display   formats as the algorithm name or 'unknown (0xNNNN)'

SslRef:
  - peer_signature_algorithm() wraps SSL_get_peer_signature_algorithm,
    returning None when BoringSSL reports the zero sentinel
    (pre-handshake, session resumption, or protocol errors). When
    called on a server-side SslRef during mTLS it surfaces the
    client-cert signature scheme.
  - signature_algorithm_used() wraps SSL_get_signature_algorithm_used,
    returning the local side's signature scheme. BoringSSL only retains
    this during the handshake; the doc comment directs callers to a
    HANDSHAKE_DONE info callback for post-handshake observation.

Tests: cover default and forced handshakes, mTLS observation of peer
and local signature schemes from both server and client sides, and the
post-handshake None contract for signature_algorithm_used.
Add `SslRef::set_verify_algorithm_prefs`, the per-connection counterpart
to the existing `SslContextBuilder::set_verify_algorithm_prefs`. This
controls the schemes advertised in the `signature_algorithms` extension
on the wire (ClientHello on a client, CertificateRequest on a server
doing mutual TLS). Useful for varying which sigalgs a given handshake
will accept from the peer without restating the full ctx.

The doc comment on `set_sigalgs_list` is updated to point at
`set_verify_algorithm_prefs` as the modern alternative; the BoringSSL
header recommends the `_prefs` accessor over the OpenSSL-compatible
helper because it does not round-trip through string parsing.

Tests: cover per-connection verify prefs accepting a satisfiable
scheme and rejecting a scheme the peer's cert cannot satisfy.
@lukevalenta lukevalenta force-pushed the mldsa-signature-algorithm branch from 7f0bf94 to 1755b06 Compare June 24, 2026 17:06
@lukevalenta lukevalenta changed the title Expose TLS signature algorithm, kex, and per-connection sigalg preferences Expose TLS signature algorithm and per-connection sigalg preferences Jun 24, 2026
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.

3 participants