JSON web tokens in OCaml
at main 268 lines 9.2 kB view raw view rendered
1# JWT and CWT Implementation TODO 2 3RFC 7519 (JWT) and RFC 8392 (CWT) compliance tracking for jsonwt. 4 5## Implementation Status 6 7### JSON Web Token (JWT) - RFC 7519 8- [x] Type definitions for all registered claims 9- [x] Type definitions for JOSE header parameters 10- [x] Type definitions for algorithms 11- [x] Base64url encoding/decoding 12- [x] Basic JWT structure parsing (3-part split) 13- [x] JSON parsing with jsont 14- [x] Signature creation and verification (HMAC, ECDSA, EdDSA) 15- [x] Claims validation 16- [x] JWK parsing and serialization 17- [x] Structured error types 18- [x] Comprehensive tests (30 tests passing) 19 20### CBOR Web Token (CWT) - RFC 8392 21- [x] Type definitions for COSE algorithms (HMAC, ECDSA, EdDSA) 22- [x] Type definitions for COSE keys (Symmetric, Ec2, Okp) 23- [x] Claims with integer keys (1=iss, 2=sub, 3=aud, 4=exp, 5=nbf, 6=iat, 7=cti) 24- [x] CBOR encoding via cbort library 25- [x] COSE_Mac0 structure (MACed CWT) 26- [x] COSE_Sign1 structure (Signed CWT) 27- [x] Signature creation and verification (HMAC, ECDSA, EdDSA) 28- [x] Claims validation (same as JWT) 29- [x] Structured error types 30- [x] Comprehensive tests (28 tests passing) 31 32### CBOR Codec - RFC 8949 33- [x] Low-level CBOR encoding primitives (Cbor_rw) 34- [x] Major type constants and encoding functions 35- [x] Integer encoding (positive and negative) 36- [x] Float encoding (IEEE 754 double precision) 37- [x] Text string and byte string encoding 38- [x] Array and map encoding 39- [x] Tag encoding 40- [x] Simple value encoding (false, true, null, undefined) 41- [x] Comprehensive tests with RFC 8949 Appendix A vectors (46 tests passing) 42 43--- 44 45## Completed Phases 46 47### Phase 0: Error Types and Core Infrastructure - DONE 48 49- [x] Structured error type with all RFC-compliant variants 50- [x] `pp_error` and `error_to_string` functions 51- [x] StringOrURI validation (validates URIs per RFC 3986) 52 53### Phase 1: JSON Parsing with jsont - DONE 54 55- [x] Header JSON codec (`Header.of_json`, `Header.to_json`) 56- [x] Claims JSON codec with strict mode for duplicate detection 57- [x] JWK JSON codec for all key types (Oct, RSA, EC, OKP) 58 59### Phase 2: Signature Operations - PARTIALLY DONE 60 61- [x] **HMAC Signatures** (HS256, HS384, HS512) - using digestif 62- [x] **ECDSA Signatures** (ES256, ES384, ES512) - using mirage-crypto-ec 63- [x] **EdDSA Signatures** (Ed25519) - using mirage-crypto-ec 64- [x] **Unsecured JWT** ("none") - with explicit `~allow_none:true` opt-in 65- [x] **Nested JWT Support** - `parse_nested` with max_depth protection 66- [ ] **RSA Signatures** (RS256, RS384, RS512) - STUBBED, needs JWK-to-RSA key parsing 67 68### Phase 3: Claims Validation - DONE 69 70- [x] Time-based claims (exp, nbf) with leeway support 71- [x] Issuer validation (iss) 72- [x] Audience validation (aud) 73- [x] `is_expired` helper function 74- [x] `time_to_expiry` helper function 75 76### Phase 4: Full JWT Creation Flow - DONE 77 78- [x] `create` function for signing JWTs 79- [x] Algorithm/key type validation 80 81### Phase 5: Tests - DONE (104 tests passing) 82 83#### JWT Tests (30 tests) 84 85**RFC Test Vectors:** 86- [x] RFC 7519 Section 3.1 HS256 JWT 87- [x] RFC 7519 Section 6.1 Unsecured JWT 88 89**Algorithm Coverage:** 90- [x] HS256 sign/verify 91- [x] HS384 sign/verify 92- [x] HS512 sign/verify 93- [ ] RS256 sign/verify (stubbed) 94- [ ] RS384 sign/verify (stubbed) 95- [ ] RS512 sign/verify (stubbed) 96- [x] ES256 sign/verify 97- [x] ES384 sign/verify 98- [x] ES512 sign/verify 99- [x] EdDSA sign/verify 100- [x] none (unsecured) with opt-in 101 102**Validation Tests:** 103- [x] Expired token rejection 104- [x] Not-yet-valid token rejection 105- [x] Issuer mismatch rejection 106- [x] Audience mismatch rejection 107- [x] Leeway handling 108 109**Error Cases:** 110- [x] Invalid base64url 111- [x] Invalid JSON 112- [x] Wrong number of parts 113- [x] Signature mismatch 114- [x] Algorithm not in allowed list 115- [x] Unsecured JWT without allow_none 116 117#### CWT Tests (28 tests) 118 119**RFC Test Vectors:** 120- [x] RFC 8392 Appendix A claims timestamps 121- [x] RFC 8392 example values (hex test vectors) 122 123**Algorithm Coverage:** 124- [x] HMAC_256_64 (alg=4) 125- [x] HMAC_256 (alg=5) 126- [x] HMAC_384 (alg=6) 127- [x] HMAC_512 (alg=7) 128- [x] ES256 (alg=-7) 129- [x] ES384 (alg=-35) 130- [x] ES512 (alg=-36) 131- [x] EdDSA (alg=-8) 132 133**COSE Key Tests:** 134- [x] Symmetric key creation 135- [x] Ed25519 key creation 136- [x] P-256 key creation 137- [x] Key ID (kid) support 138 139**Claims Tests:** 140- [x] Claims builder 141- [x] Timestamp claims (exp, nbf, iat) 142- [x] Single and multiple audience 143- [x] CWT ID (cti) 144- [x] CBOR serialization 145 146**Validation Tests:** 147- [x] Expired token rejection 148- [x] Not-yet-valid token rejection 149- [x] Issuer validation 150- [x] Audience validation 151- [x] Leeway handling 152 153#### CBOR Tests (46 tests) 154 155**RFC 8949 Appendix A Test Vectors:** 156- [x] Unsigned integers (0-1000000000000) 157- [x] Negative integers (-1 to -1000) 158- [x] Booleans and null 159- [x] Floats (1.0, 1.1, -4.1, 1.0e+300, Infinity, NaN) 160- [x] Text strings (empty, ASCII, UTF-8 with Unicode) 161- [x] Byte strings 162- [x] Arrays (empty, nested, 25 items) 163- [x] Maps (empty, int keys, string keys, nested) 164- [x] Tags (epoch timestamp) 165- [x] Constants (major types, simple values, additional info) 166 167--- 168 169## Remaining Work 170 171### JWT: RSA Signatures (RS256, RS384, RS512) 172 173**Status:** Stubbed - returns `Key_type_mismatch "RSA signing/verification not yet implemented"` 174 175**Required:** 1761. Implement JWK-to-RSA key parsing for `n`, `e` (public) and `d`, `p`, `q`, `dp`, `dq`, `qi` (private) fields 1772. Use `mirage-crypto-pk` for RSASSA-PKCS1-v1_5 signatures 1783. Add tests with RFC test vectors 179 180### CWT: CBOR Decoding 181 182**Status:** Not implemented - current implementation only encodes CWTs 183 184**Required:** 1851. Add CBOR decoding functions to Cbor_rw module 1862. Implement `Cwt.parse` to decode CWT from CBOR bytes 1873. Add tests with RFC 8392 Appendix A encoded test vectors 188 189### CWT: COSE Key Encoding/Decoding 190 191**Status:** Keys are created in memory but not serialized 192 193**Required:** 1941. Add `Cose_key.to_cbor` and `Cose_key.of_cbor` functions 1952. Follow RFC 9052 Section 7 (COSE Key) format 1963. Add tests with RFC test vectors 197 198### CWT: CWT Tag Support 199 200**Status:** Partial - encodes COSE structures but not outer CWT tag 201 202**Required:** 2031. Add support for CWT tag (61) wrapping per RFC 8392 Section 2 2042. Add support for optional outer COSE tag per RFC 9052 205 206### Future Work (Not in Current Scope) 207 2081. **JWK Set (JWKS)**: RFC 7517 Section 5 support for multiple keys 209 - Useful for key rotation and fetching keys from JWKS endpoints 210 - Example: `/.well-known/jwks.json` 211 - Consider adding `Jwks.t` type and `Jwks.find_key : kid:string -> Jwks.t -> Jwk.t option` 212 2132. **JWE Support**: RFC 7516 JSON Web Encryption 214 - Required for encrypted JWTs (as opposed to signed JWTs) 215 - Lower priority unless needed for specific use cases 216 217--- 218 219## Design Decisions (Implemented) 220 2211. **StringOrURI validation**: YES - Validates that `iss`/`sub` values containing ":" are valid URIs per RFC 3986. 222 2232. **Duplicate claims**: STRICT MODE - Rejects JWTs with duplicate claim names by default. `~strict:false` allows lenient parsing. 224 2253. **"none" algorithm**: REQUIRE OPT-IN - `~allow_none:bool` parameter to `verify` (default false). Unsecured JWTs rejected unless explicitly allowed. 226 2274. **Error types**: STRUCTURED - Proper error variant type for pattern matching and error handling. 228 2295. **Algorithm allowlist**: YES - `~allowed_algs` parameter to `verify`, defaulting to all algorithms (except none). 230 2316. **Clock source**: EXPLICIT - Always requires `~now:Ptime.t` parameter. No implicit system clock usage. 232 2337. **Nested JWTs**: YES - Support via `parse_nested` with `~max_depth` protection (default 2). 234 235--- 236 237## File Summary 238 239| File | Lines | Description | 240|------|-------|-------------| 241| `lib/jsonwt.ml` | ~1010 | JWT implementation | 242| `lib/jsonwt.mli` | ~480 | JWT interface with RFC documentation | 243| `lib/cwt.ml` | ~760 | CWT implementation | 244| `lib/cwt.mli` | ~400 | CWT interface with RFC documentation | 245| `cbort/cbor_rw.ml` | ~200 | Low-level CBOR encoding primitives | 246| `cbort/cbor_rw.mli` | ~200 | CBOR encoding interface | 247| `cbort/cbort.ml` | ~300 | CBOR codec for jsont types | 248| `cbort/cbort.mli` | ~100 | CBOR codec interface | 249| `test/test_jsonwt.ml` | ~440 | 30 JWT tests | 250| `test/test_cwt.ml` | ~500 | 28 CWT tests | 251| `test/test_cbor.ml` | ~320 | 46 CBOR encoding tests | 252 253--- 254 255## References 256 257### JWT (JSON Web Token) 258- [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519) - JSON Web Token (JWT) 259- [RFC 7515](https://datatracker.ietf.org/doc/html/rfc7515) - JSON Web Signature (JWS) 260- [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517) - JSON Web Key (JWK) 261- [RFC 7518](https://datatracker.ietf.org/doc/html/rfc7518) - JSON Web Algorithms (JWA) 262- [RFC 8037](https://datatracker.ietf.org/doc/html/rfc8037) - CFRG Elliptic Curve (EdDSA) 263 264### CWT (CBOR Web Token) 265- [RFC 8392](https://datatracker.ietf.org/doc/html/rfc8392) - CBOR Web Token (CWT) 266- [RFC 9052](https://datatracker.ietf.org/doc/html/rfc9052) - CBOR Object Signing and Encryption (COSE) Structures 267- [RFC 9053](https://datatracker.ietf.org/doc/html/rfc9053) - CBOR Object Signing and Encryption (COSE) Algorithms 268- [RFC 8949](https://datatracker.ietf.org/doc/html/rfc8949) - Concise Binary Object Representation (CBOR)