Skip to content

Add JWK parsing limits and align TS implementation with Rust#15

Merged
eacet merged 3 commits intomainfrom
fix/pq-key-encoder/ts/align-with-rust-impl
Feb 24, 2026
Merged

Add JWK parsing limits and align TS implementation with Rust#15
eacet merged 3 commits intomainfrom
fix/pq-key-encoder/ts/align-with-rust-impl

Conversation

@eacet
Copy link
Member

@eacet eacet commented Feb 20, 2026

fromJWKString / toJWKString — new functions for JSON string round-trips with the same resource limits (64 KiB size, 32 fields, duplicate known field rejection)
Base64 trailing bits validation (RFC 4648 §3.5) — reject non-canonical base64 matching Rust strictness
kid field support — toJWK accepts kid option, fromJWK validates kid type
Test coverage — from 53 → 86 tests; all 18 algorithms round-tripped through JWK object and JSON string paths, plus error cases for bad kty/alg/x/d, size mismatch, oversized input, field count, and duplicates

Copy link
Member Author

eacet commented Feb 20, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@eacet eacet changed the title Align TS imple with Rust Add JWK parsing limits and align TS implementation with Rust Feb 20, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ac206a0d2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@greptile-apps
Copy link

greptile-apps bot commented Feb 20, 2026

Greptile Summary

This PR aligns the TypeScript pq-key-encoder implementation with the Rust counterpart by adding three major features:\n\n- kid (Key ID) support: Optional kid field added to JwkExportOptions, PQJwkBase, and all JWK export/import paths. The field is conditionally included only when provided (avoiding kid: undefined in serialized output).\n- toJWKString / fromJWKString functions: New string-level JWK serialization with resource limits matching Rust — 64 KiB input size cap, 32-field maximum, and duplicate detection for known fields (kty, alg, x, d, kid). A custom extractTopLevelKeys parser handles JSON string escaping and nesting depth.\n- RFC 4648 §3.5 trailing bits validation: Base64 decoding now rejects non-canonical encodings with non-zero trailing bits, matching Rust's strict behavior.\n\nTest coverage is thorough: the rewritten test suite covers all 18 algorithms for round-trip through both toJWK/fromJWK and toJWKString/fromJWKString, plus error cases and resource limit enforcement.

Confidence Score: 4/5

  • This PR is safe to merge — the changes are well-tested, correctly align with the Rust implementation, and introduce no regressions.
  • Score of 4 reflects solid implementation with comprehensive test coverage across all 18 algorithms, proper resource limit enforcement, and correct RFC 4648 trailing bits validation. Minor style observations exist but no functional issues were found. The custom JSON key extractor is correct for the use case but adds surface area that could theoretically be exercised by adversarial input.
  • packages/pq-key-encoder/ts/src/jwk.ts deserves the most attention due to the new extractTopLevelKeys custom parser and the fromJWKString resource limit logic.

Important Files Changed

Filename Overview
packages/pq-key-encoder/ts/src/jwk.ts Adds kid support to toJWK/fromJWK, new toJWKString/fromJWKString with resource limits (64 KiB size, 32 fields, duplicate detection), and custom extractTopLevelKeys JSON parser. Logic is sound and aligns with Rust implementation.
packages/pq-key-encoder/ts/src/types.ts Adds optional kid field to JwkExportOptions. Minimal, correct change consistent with the PQJwkBase type that already has kid.
packages/pq-key-encoder/ts/src/utils/base64.ts Adds RFC 4648 §3.5 trailing bits validation to reject non-canonical base64 encodings, matching Rust behavior. Adds pre-computed BASE64_VALUES lookup table. Implementation is correct.
packages/pq-key-encoder/ts/tests/jwk.test.ts Comprehensive rewrite: removes redundant local type definitions, imports from source directly, adds tests for kid support, fromJWK error cases, toJWKString/fromJWKString with resource limits, and exhaustive round-trip tests for all 18 algorithms.
packages/pq-key-encoder/ts/tests/utils/base64.test.ts Adds tests for RFC 4648 trailing bits validation, base64url trailing bits rejection, and round-trip tests for lengths 0-50 in both base64 and base64url.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    subgraph "toJWK / toJWKString"
        A[KeyData + Options] --> B{key.type?}
        B -->|public| C[encodeBase64Url bytes]
        B -->|private| D{includePrivate?}
        D -->|false| C
        D -->|true| E[encodeBase64Url public + private]
        C --> F{kid provided?}
        E --> F
        F -->|yes| G[Add kid to JWK]
        F -->|no| H[PQJwk]
        G --> H
        H -->|toJWKString| I[JSON.stringify]
    end

    subgraph "fromJWKString"
        J[JSON string] --> K{size ≤ 64 KiB?}
        K -->|no| L[Error: max size]
        K -->|yes| M[extractTopLevelKeys]
        M --> N{fields ≤ 32?}
        N -->|no| O[Error: too many fields]
        N -->|yes| P{duplicate known fields?}
        P -->|yes| Q[Error: duplicate field]
        P -->|no| R[JSON.parse]
        R --> S[fromJWK]
    end

    subgraph "fromJWK"
        S --> T{Validate kty, alg, x, d, kid}
        T -->|invalid| U[InvalidInputError]
        T -->|valid| V[decodeBase64Url x]
        V --> W[validateTrailingBits RFC 4648]
        W --> X{has d field?}
        X -->|yes| Y[decodeBase64Url d → private KeyData]
        X -->|no| Z[public KeyData]
    end
Loading

Last reviewed commit: 7ac206a

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@eacet eacet requested a review from snwfdhmp February 22, 2026 00:54
Copy link
Member

@snwfdhmp snwfdhmp left a comment

Choose a reason for hiding this comment

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

I left a comment

@eacet eacet requested a review from snwfdhmp February 23, 2026 15:22
@eacet eacet merged commit 05cdeb8 into main Feb 24, 2026
6 checks passed
@eacet eacet deleted the fix/pq-key-encoder/ts/align-with-rust-impl branch February 24, 2026 09:02
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.

2 participants