### Description
<!-- Explain what you did, what you expected to happen, and what actually happened. --> I used `jwt_verify()` function and expected to automatically handle the expiration check. But it doesn't.
### Troubleshooting
#### Reproduction Have the following Kamailio config: ``` loadmodule "jwt.so" ... modparam("jwt", "key_mode", 0) .... $var(authorization_header_value) = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxNDQ0ODEiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjExMTYyMzkwMjJ9.Ce0o-10D-ghrfQ8jAZTFgJxw6pufLa6gtoCsylI9cPQo2MANVKV1sjwwKtbLfPzSobz1VhOVZ3RtbFME1GKwEOQq0MuNh7EsmMypjAyBbSPj3he0H4ysa3Lt2i8nJ2Z02j_PU387EEwziC4ilkbXNLXdx43ji_SP--dF3rij2C1Wv8AWbNloPnIAIgtTMdXRuxQPPGFhpBLfUPa54dgrRjLRSGzUJKNbszVljhpzqLM6rJ7hsf2MiB3Ww0goRH7r_9-rm4s9eYMK1xaCPlxBUIxw9bVbNkpiFypq_IcdhXnfyTsF4FUuXSgoUqGD6dOCOh6umsDfl7rrBTMRDdqT1CcBj-_CIWSwmxreVxYz1ET5cZe0oj1GnZRYFXrJzUFd1y9srV6qKY-QK1hlflONd_YZ23hpT1hXOVF0fsgB5JQBjDYBi2kLKms5zi-EAmoIVr1JVJS5-tE_iS3p40YGblI0oOOfxeKCtskgl9KtsRvUWi_25pU5BOEX8KiXVkJ2MH9KFYv2-HXrBVkZyY4kCsHIedz8k_nMfOICrh932pC2bgkQLJEZLSwtO8nTK5G1OrS_VLYwqJv0oGtnmcupexTGYiDjN6t1nqnH6s6409z16M-pKG2wwrt-40sFJh-5eDrpqs8KreSDdOYZsoB5POn7ipqZ0OfbVUCT4TzYYPA"; $var(jwt_verification) = jwt_verify("/etc/kamailio/oauth_pub.pem", "RS256", "sub='$fU'", "$var(authorization_header_value)" ); xlog("JWT verification Status: $var(jwt_verification)"); #Outputs 1 ... ``` If you decode the JWT you'll see that the timestamp in the `iat` header is in the past.
#### Debugging Data
#### Log Messages
``` {1 90377072 REGISTER 1d0833c1-0d75-123e-8abe-560004469ea4} <script>: JWT verification Status: 1 ```
### Possible Solutions
Compare the timestamp from the token's `iat` claim with the current timestamp and fail the verification if it's in the past.
### Additional Information
* **Kamailio Version** - output of `kamailio -v`
``` version: kamailio 5.8.2 (x86_64/linux) 3fa5f4 flags: USE_TCP, USE_TLS, USE_SCTP, TLS_HOOKS, USE_RAW_SOCKS, DISABLE_NAGLE, USE_MCAST, DNS_IP_HACK, SHM_MMAP, PKG_MALLOC, MEM_JOIN_FREE, Q_MALLOC, F_MALLOC, TLSF_MALLOC, DBG_SR_MEMORY, USE_FUTEX, FAST_LOCK-ADAPTIVE_WAIT, USE_DNS_CACHE, USE_DNS_FAILOVER, USE_NAPTR, USE_DST_BLOCKLIST, HAVE_RESOLV_RES, TLS_PTHREAD_MUTEX_SHARED ADAPTIVE_WAIT_LOOPS 1024, MAX_RECV_BUFFER_SIZE 262144, MAX_SEND_BUFFER_SIZE 262144, MAX_URI_SIZE 1024, BUF_SIZE 65535, DEFAULT PKG_SIZE 8MB poll method support: poll, epoll_lt, epoll_et, sigio_rt, select. id: 3fa5f4 compiled on 10:39:56 Jun 12 2024 with gcc 8.5.0 ```
* **Operating System**:
<!-- Details about the operating system, the type: Linux (e.g.,: Debian 8.4, Ubuntu 16.04, CentOS 7.1, ...), MacOS, xBSD, Solaris, ...; Kernel details (output of `lsb_release -a` and `uname -a`) -->
``` Rocky Linux 8.10 (Green Obsidian) ```
The `iat` is `Issued At`:
- https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6
If its value is in the past, that seems to be ok.
The validation is done by libjwt.
@miconda My bad. I was referring to the `exp` claim.
_Note: Updated the issue._
What did you update? The description still refers to `iat` checking.
I tested with the next snippet and validation failed:
``` jwt_generate("../etc/rsa256-prv.pem", "RS256", "data='xyz';exp=1116239032"); xinfo("====jwt: [$jwt(val)]\n"); if(jwt_verify("../etc/rsa256-pub.pem", "RS256", "data='xyz'", "$jwt(val)")) { xinfo("====jwt: validated\n"); } else { xinfo("====jwt: not-validated\n"); } ```
The `exp` value is taken from your example.
If it fails for you, ask to reopen.
Closed #4007 as completed.