Skip to content

feat: add method to get signature scheme name#5471

Merged
lrstewart merged 3 commits intoaws:mainfrom
lrstewart:getters
Aug 26, 2025
Merged

feat: add method to get signature scheme name#5471
lrstewart merged 3 commits intoaws:mainfrom
lrstewart:getters

Conversation

@lrstewart
Copy link
Copy Markdown
Contributor

@lrstewart lrstewart commented Aug 20, 2025

Release Summary:

Add new s2n_connection_get_signature_scheme method to retrieve the IANA description of the server signature scheme

Resolved issues:

Description of changes:

Add a getter for signature_schemes, modeled after s2n_connection_get_key_exchange_group.

This meets a customer request for easier logging, specifically for PQ signatures (MLDSA). That means that the customer is primarily interested in actual, official TLS1.3 signature schemes.

Call-outs:

How should we handle non-IANA signature schemes?

We could:

  1. Error if no official signature scheme
  2. Return a combo of "signature algorithm" and "hash algorithm"

I went with 2. I worry that 1 would be awkward for customers to use. The primary use case for this API is for logging, but 1 would probably require checking the actual protocol version every time you perform the logging to avoid errors. Since TLS1.2 can also sometimes choose an official signature scheme, the behavior might be even more confusing and inconsistent if we didn't always treat actual_protocol_version<S2N_TLS13 as an error.

How should we format non-IANA signature scheme names?

We could use:

  1. "<signature_algorithm>+<hash_algorithm>"
  2. "legacy_<signature_algorithm>_<hash_algorithm>"
  3. "legacy_<signature_algorithm, with '_pkcs1' if 'rsa'>_<hash_algorithm>"

I went with 2. I think the "legacy" in front is a clear indicator for non-IANA names.

I initially liked 1, but I think seeing it appear in policy snapshots made how odd it would look very clear:

- rsa_pkcs1_sha384
- rsa_pkcs1_sha512
- rsa+sha224
- ecdsa_sha256
- ecdsa_sha384
- ecdsa_sha512
- ecdsa+sha224
- rsa_pkcs1_sha1
- ecdsa_sha1

To me, it's jarring to see the random "+" but also simultaneously not obvious that the "+" indicates non-IANA / legacy.

Our names currently follow 3. I like how that matches the official names, but I worry that's not well defined enough: it's easier to say "combine the IANA descriptions of the signature algorithm and hash algorithm" than "combine the IANA descriptions of the signature algorithm and hash algorithm, and append _pkcsa1 to any rsa signature algorithms". Like documenting that would probably get confusing. We'll need to merge #5472 first if we want 2 instead of 3.

How should we handle no signature at all?

No signature scheme will be chosen if no signature is used, such as for session resumption. In that case, we could:

  1. Treat it as an error.
  2. Return NULL
  3. Return "none"

I'd vote for "none". NULL also seems reasonable, but I worry about the usual issues around handling unexpected NULLs. And if a customer was using this method for logging / metrics, they'd still probably need to map NULL -> "none".

I really don't want to treat it as an error because that will make the method very hard to use. Customers shouldn't need to determine whether their connection negotiated a signature scheme or not in order to call this method or handle its errors.

Testing:

New unit tests.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@github-actions github-actions bot added the s2n-core team label Aug 20, 2025
@lrstewart lrstewart marked this pull request as ready for review August 20, 2025 19:23
struct s2n_signature_scheme {
uint16_t iana_value;
const char *iana_name;
const char *name;
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.

These names aren't ALWAYS IANA names even rn, so I wanted to change the field name.

POSIX_ENSURE_REF(scheme_name);

const struct s2n_signature_scheme *scheme = conn->handshake_params.server_cert_sig_scheme;
POSIX_ENSURE(scheme, S2N_ERR_INVALID_STATE);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Probably not in scope for this, but I wonder if it would be worth having an S2N_ERR_UNAVAILABLE err.

Because in the event of RSA kx/session resumption, it is technically invalid to call the API, but that almost sounds too harsh.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also I'd vote to add a test for the RSA kx/session resumption edge cases. E.g. to make sure we don't accidentally surface s2n_null_sig_scheme in the future?

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.

I wonder if following the key_exchange model was wrong, and the method should just return const char* instead of int? Then "errors" would just be NULL.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Couldn't scheme_name still be set to null on an error with the current design?

* 2. An unofficial description, if the server signature did not use an official
* IANA signature scheme. This description will take the form
* "legacy_<signature_algorithm>_<hash_algorithm>".
* For example, legacy_rsa_sha224 or legacy_ecdsa_sha256.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit

Suggested change
* For example, legacy_rsa_sha224 or legacy_ecdsa_sha256.
* For example, legacy_rsa_pkcs1_sha224 or legacy_ecdsa_sha256.

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.

Not once I merge #5472 >:)

@lrstewart lrstewart enabled auto-merge August 26, 2025 04:34
@lrstewart lrstewart added this pull request to the merge queue Aug 26, 2025
Merged via the queue into aws:main with commit 23cc058 Aug 26, 2025
50 checks passed
@lrstewart lrstewart deleted the getters branch August 26, 2025 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants