RFC7518 Section 6.2 Byte Count Conformance#91
RFC7518 Section 6.2 Byte Count Conformance#91justin-lovell wants to merge 4 commits intoauthlib:mainfrom
Conversation
These changes are to conform to the explicit requirements of payload sizes according to section 6.2 on RFC7518. 6.2.1.2 and 6.2.1.3 > The length of this octet string MUST be the full size of a > coordinate for the curve specified in the "crv" parameter. 6.2.2.1 > The length of this octet string MUST be ceiling(log-base-2(n)/8) > octets (where n is the order of the curve)
There was a problem hiding this comment.
Pull request overview
Improves EC JWK serialization to ensure curve integers are encoded at the full, fixed byte length required by RFC 7518 §6.2 (preserving leading zero octets), and adds tests to validate the exported base64url lengths for common NIST curves.
Changes:
- Extend
int_to_base64to support fixed-width integer encoding via an optionalbyte_count. - Update EC key export to always encode
x,y, anddusing the curve’s fixed byte size. - Add tests asserting fixed base64url string lengths for P-256, P-384, and P-521 exports.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
src/joserfc/util.py |
Adds optional fixed-width support to integer→base64url encoding used by JWK exporters. |
src/joserfc/_rfc7518/ec_key.py |
Exports EC key parameters using fixed byte counts to avoid truncating leading zeros. |
tests/jwk/test_ec_key.py |
Adds tests ensuring EC JWK exports always emit base64url values of expected fixed length. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if byte_count is None: | ||
| byte_count = (num.bit_length() + 7) // 8 |
There was a problem hiding this comment.
int_to_base64 now accepts an explicit byte_count, but it doesn’t validate that byte_count is large enough to hold num. If a caller passes a too-small value, int.to_bytes raises OverflowError, which is a less clear API failure mode. Consider validating byte_count >= (num.bit_length() + 7) // 8 (and byte_count >= 0) and raising a ValueError with a helpful message when it’s invalid.
| if byte_count is None: | |
| byte_count = (num.bit_length() + 7) // 8 | |
| required_bytes = (num.bit_length() + 7) // 8 | |
| if byte_count is None: | |
| byte_count = required_bytes | |
| else: | |
| if byte_count < 0: | |
| raise ValueError("byte_count must be non-negative") | |
| if byte_count < required_bytes: | |
| raise ValueError("byte_count is too small to represent num") |
There was a problem hiding this comment.
This ensures the pre-existing behavior remains as-is. However, I suspect that this needs to be adjusted for the RSA keys (section 6.3 of RFC7518) -- I will send a follow up PR when satisfied with the correct implementation.
7ec5f41 to
f881c6a
Compare
|
I've updated the code according to the feedback provided by Copilot. Python isn't used in my day job, so if there are other improvements please point it out. The non-conformance to the RFC7518 specification was discovered when inspecting application logs failed to emit valid ephemeral key parameters in ECDH-ES+A256KW payloads. |
This pull request improves the handling of EC (Elliptic Curve) key serialization to ensure that integer values are always encoded to the full byte size required by the curve, preventing potential truncation of leading zeros and ensuring compliance with RFC 7518. It also adds comprehensive tests to verify this behavior for different curve types.
Tests Implemented
Introduced new tests in
test_ec_key.pyto verify that exported EC keys for the P-256, P-384, and P-521 curves always emit base64url-encoded values of the expected full length, regardless of the leading zeros in the underlying integer values.