--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2025 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <errno.h>
+
+#include <json.h>
+
+#include <pakfire/base64.h>
+#include <pakfire/ctx.h>
+#include <pakfire/json.h>
+#include <pakfire/jwt.h>
+
+static int pakfire_jwt_find_payload(const char* token, const char** payload, size_t* length) {
+ const char* p = NULL;
+ size_t l = 0;
+
+ // Walk through the token character by character...
+ while (token && *token) {
+ switch (*token++) {
+ case '.':
+ // If we have found the first dot, the payload starts right after it
+ if (!p) {
+ p = token;
+
+ // If we have hit the second dot, we have found the end of the payload
+ } else {
+ // Determine the length
+ l = token - p - 1;
+
+ // Terminate the loop
+ token = NULL;
+ }
+ break;
+ }
+ }
+
+ // If the payload is empty, we return an error
+ if (!p || !l)
+ return -EINVAL;
+
+ // Return the values
+ *payload = p;
+ *length = l;
+
+ return 0;
+}
+
+static int pakfire_jwt_decode_payload(char** payload, size_t* length, const char* token) {
+ const char* p = NULL;
+ size_t l = 0;
+ int r;
+
+ // Find the payload
+ r = pakfire_jwt_find_payload(token, &p, &l);
+ if (r < 0)
+ return r;
+
+ // Decode the payload
+ return pakfire_b64decode((unsigned char**)payload, length, p, l);
+}
+
+int pakfire_jwt_payload(struct pakfire_ctx* ctx, const char* token, struct json_object** payload) {
+ char* p = NULL;
+ size_t l = 0;
+ int r;
+
+ // Decode the payload
+ r = pakfire_jwt_decode_payload(&p, &l, token);
+ if (r < 0) {
+ ERROR(ctx, "Failed to decode the JWT payload: %s\n", strerror(-r));
+ return r;
+ }
+
+ // Parse the JSON
+ *payload = pakfire_json_parse(ctx, p, l);
+ if (!*payload)
+ return -EINVAL;
+
+ return 0;
+}
+
+time_t pakfire_jwt_expires_at(struct pakfire_ctx* ctx, const char* token) {
+ struct json_object* payload = NULL;
+ time_t expires_at = -1;
+ int r;
+
+ // Parse the payload
+ r = pakfire_jwt_payload(ctx, token, &payload);
+ if (r < 0)
+ goto ERROR;
+
+ // Fetch the expiry time
+ r = pakfire_json_get_int64(payload, "exp", &expires_at);
+ if (r < 0)
+ goto ERROR;
+
+ // Return the expiry time
+ r = expires_at;
+
+ERROR:
+ if (payload)
+ json_object_put(payload);
+
+ return r;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2025 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_JWT_H
+#define PAKFIRE_JWT_H
+
+#include <json.h>
+
+#include <pakfire/ctx.h>
+
+int pakfire_jwt_payload(struct pakfire_ctx* ctx,
+ const char* token, struct json_object** payload);
+
+time_t pakfire_jwt_expires_at(struct pakfire_ctx* ctx, const char* token);
+
+#endif /* PAKFIRE_JWT_H */