)]}'
{
  "commit": "f4a536fe70aa37e454e4b2ead3b01281f1fe0f40",
  "tree": "8929f5f8d0a2c745224dfc18bae0817715167f99",
  "parents": [
    "86cedec34cdfd10068ed5608b367985902259158"
  ],
  "author": {
    "name": "Ben Collins",
    "email": "bcollins@libjwt.io",
    "time": "Thu Jun 18 03:51:15 2026 -0400"
  },
  "committer": {
    "name": "Ben Collins",
    "email": "bcollins@libjwt.io",
    "time": "Thu Jun 18 03:51:15 2026 -0400"
  },
  "message": "jwt: route key operations to the backend that parsed the key\n\nA jwk_item is bound to the crypto backend active when its JWK was parsed\n(item-\u003eprovider). Previously, signing/verifying or JWE-encrypting with that\nkey under a DIFFERENT active backend failed (\"Key is not compatible\" on\nOpenSSL/MbedTLS; GnuTLS silently re-imported from the JWK JSON).\n\nAdd jwt_item_ops(), which resolves a key\u0027s origin backend from the ops\nregistry, and dispatch the asymmetric key operations through it: sign/verify\n(jwt.c) and the JWE ECDH-ES and RSA key-management paths (jwe.c). Keys with no\nbackend-specific material (\"oct\" / JWT_CRYPTO_OPS_ANY) and key-free operations\n(content encryption on a raw CEK, the CSPRNG, the RFC 7638 thumbprint digest,\nJWK JSON export) continue to use the active backend.\n\nMixed-backend usage now \"just works\", OpenSSL/GnuTLS/MbedTLS behave\nconsistently, and the \"set crypto ops before loading keys\" ordering\nrequirement (the root cause behind #321) is no longer needed.\n\ntests/jwt_xbackend.c exercises the full (parse-backend, use-backend) matrix:\nfor each pair a key parsed under one backend signs+verifies (EC ES256, RSA\nRS256, oct HS256) and round-trips JWE (RSA-OAEP-256, ECDH-ES) under another.\nVerified across all three backends under both JSON backends locally\n(MbedTLS 4.1) and in the CI image (MbedTLS 3.6.6).\n\nCloses #320\n\nCo-Authored-By: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\nSigned-off-by: Ben Collins \u003cbcollins@libjwt.io\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "4ac53d43c86e1303df52962d09f42da00cc4d757",
      "old_mode": 33188,
      "old_path": "CMakeLists.txt",
      "new_id": "f7645602d1baaed377bd52642bac1be18e97486b",
      "new_mode": 33188,
      "new_path": "CMakeLists.txt"
    },
    {
      "type": "modify",
      "old_id": "62768245e706e2eae7484dd105b186c8b481158e",
      "old_mode": 33188,
      "old_path": "include/jwt.h",
      "new_id": "ac9f8efd3ff6a49a8068ba2a768e94bd015548bf",
      "new_mode": 33188,
      "new_path": "include/jwt.h"
    },
    {
      "type": "modify",
      "old_id": "1eb6f7992b25480958cb95357712e70c6b770e9f",
      "old_mode": 33188,
      "old_path": "libjwt/jwe.c",
      "new_id": "2f1b50957fcd4faa9647e9975e62009c42efbb7f",
      "new_mode": 33188,
      "new_path": "libjwt/jwe.c"
    },
    {
      "type": "modify",
      "old_id": "0df838abdb15d03e570d12af9f452aff0bd5d755",
      "old_mode": 33188,
      "old_path": "libjwt/jwt-crypto-ops.c",
      "new_id": "069418a224082165c821802c4a8dda3d2aa79232",
      "new_mode": 33188,
      "new_path": "libjwt/jwt-crypto-ops.c"
    },
    {
      "type": "modify",
      "old_id": "b744adf78f539a12dc4cbfaba13810b17df06040",
      "old_mode": 33188,
      "old_path": "libjwt/jwt-private.h",
      "new_id": "3600c6a72ab4dd22d8fc186d66c4989968da829e",
      "new_mode": 33188,
      "new_path": "libjwt/jwt-private.h"
    },
    {
      "type": "modify",
      "old_id": "6cf6c9095ef54f6246360e8f04acf321e09d63f3",
      "old_mode": 33188,
      "old_path": "libjwt/jwt.c",
      "new_id": "ad5b3dea755127193460d8f58afb71d07edfa5e1",
      "new_mode": 33188,
      "new_path": "libjwt/jwt.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f91c0f2fcd92feb29b265970dcc1db2082effaf4",
      "new_mode": 33188,
      "new_path": "tests/jwt_xbackend.c"
    }
  ]
}
