Skip to content
This repository has been archived by the owner on Sep 19, 2024. It is now read-only.

Commit

Permalink
add fastjson, implement basic verification
Browse files Browse the repository at this point in the history
  • Loading branch information
bonifaido committed Mar 6, 2024
1 parent 6742280 commit 8681486
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 49 deletions.
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
path = third-party/BearSSL
url = https://github.com/bonifaido/BearSSL.git
branch = linux-kernel
[submodule "third-party/fastjson"]
path = third-party/fastjson
url = https://github.com/bonifaido/json.c
branch = linux-kernel
2 changes: 2 additions & 0 deletions .vscode/c_cpp_properties.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
"${linux-src}/arch/arm64/include/generated/",
"${linux-src}/arch/arm64/include/uapi/",
"${linux-src}/arch/arm64/include/generated/uapi/",
"third-party/",
"third-party/base64/",
"third-party/BearSSL/inc/",
"third-party/fastjson/",
"third-party/parson/",
"third-party/picohttpparser/",
"third-party/wasm3/source/"
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ccflags-y += -foptimize-sibling-calls \
-DDEBUG=1 \
-Dd_m3HasFloat=$(EMULATE_FLOATS) \
-I$(PWD) \
-I$(PWD)/third-party/ \
-I$(PWD)/third-party/BearSSL/inc/ \
-I$(PWD)/third-party/wasm3/source/ \
-I$(PWD)/third-party/base64 \
Expand Down Expand Up @@ -60,6 +61,7 @@ camblet-objs := third-party/wasm3/source/m3_api_libc.o \
third-party/wasm3/source/m3_module.o \
third-party/wasm3/source/m3_parse.o \
third-party/base64/base64.o \
third-party/fastjson/json.o \
third-party/parson/json.o \
third-party/picohttpparser/picohttpparser.o \
buffer.o \
Expand Down
84 changes: 40 additions & 44 deletions jwt.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
#include "base64.h"
#include "crypto.h"
#include "jwt.h"
#include "json.h"
#include "fastjson/json.h"

#include <linux/slab.h>

jwt_t *jwt_parse(const char *jwt, const char *secret)
jwt_t *jwt_parse(const char *jwt, const unsigned len)
{
jwt_t *j = kzalloc(sizeof(jwt_t), GFP_KERNEL);
if (!j)
Expand Down Expand Up @@ -47,25 +48,22 @@ jwt_t *jwt_parse(const char *jwt, const char *secret)

printk(KERN_INFO "header_json: '%s'\n", header_json);

JSON_Value *header = json_parse_string(header_json);
if (!header)
struct json header = json_parse(header_json);
if (!json_exists(header))
{
kfree(j);
kfree(header_json);
return NULL;
}

JSON_Object *header_obj = json_value_get_object(header);

j->alg = json_object_get_string(header_obj, "alg");
j->typ = json_object_get_string(header_obj, "typ");
j->alg = json_raw(json_object_get(header, "alg"));
j->typ = json_raw(json_object_get(header, "typ"));

char *payload_end = strchr(header_end + 1, '.');
if (!payload_end)
{
kfree(j);
kfree(header_json);
json_value_free(header);
return NULL;
}

Expand All @@ -74,7 +72,6 @@ jwt_t *jwt_parse(const char *jwt, const char *secret)
{
kfree(j);
kfree(header_json);
json_value_free(header);
return NULL;
}

Expand All @@ -84,70 +81,69 @@ jwt_t *jwt_parse(const char *jwt, const char *secret)
kfree(j);
kfree(header_json);
kfree(payload_json);
json_value_free(header);
return NULL;
}

printk(KERN_INFO "payload_json: '%s'\n", payload_json);

JSON_Value *payload = json_parse_string(payload_json);
if (!payload)
struct json payload = json_parse(payload_json);
if (!json_exists(payload))
{
kfree(j);
kfree(header_json);
kfree(payload_json);
json_value_free(header);
return NULL;
}

JSON_Object *payload_obj = json_value_get_object(payload);

j->iss = json_object_get_string(payload_obj, "iss");
j->sub = json_object_get_string(payload_obj, "sub");
j->aud = json_object_get_string(payload_obj, "aud");
j->exp = json_object_get_number(payload_obj, "exp");
j->iss = json_raw(json_object_get(payload, "iss"));
j->sub = json_raw(json_object_get(payload, "sub"));
j->aud = json_raw(json_object_get(payload, "aud"));
j->exp = json_raw(json_object_get(payload, "exp"));

// signature parsing
char *signature = payload_end + 1;
j->signature = payload_end + 1;
j->signature_len = jwt + len - j->signature;

j->data = jwt;
j->data_len = payload_end - jwt;

// TODO free all values

return j;
}

printk("calculating hash for [%d bytes]: %.*s", payload_end - jwt, payload_end - jwt, jwt);
void jwt_free(jwt_t *jwt)
{
kfree(jwt);
}

char *hash = hmac_sha256(jwt, payload_end - jwt, secret, strlen(secret));
int jwt_verify(jwt_t *jwt, const char *secret, const unsigned secret_len)
{
printk("calculating hash for [%d bytes]: %.*s", jwt->data_len, jwt->data_len, jwt->data);

char *hash = hmac_sha256(jwt->data, jwt->data_len, secret, strlen(secret));
if (!hash)
{
printk(KERN_ERR "failed to calculate hmac");

kfree(j);
kfree(header_json);
kfree(payload_json);
json_value_free(header);
printk(KERN_ERR "failed to calculate hmac for jwt");

return NULL;
return -1;
}

char hash_base64[256];

int bytes = base64_encode(hash_base64, 256, hash, 32);

if (bytes < 0)
{
printk(KERN_ERR "failed to base64 encode signature");

kfree(j);
kfree(header_json);
kfree(payload_json);
json_value_free(header);

return NULL;
kfree(hash);
return -1;
}

printk("signature [%d bytes]: %s", strlen(signature), signature);
printk("hash_base64 [%d bytes]: %s", bytes, hash_base64);
kfree(hash);

return j;
}
printk("signature [%d bytes]: %s", jwt->signature_len, jwt->signature);
printk("hash_base64 [%d bytes]: %s", bytes, hash_base64);

void jwt_free(jwt_t *jwt)
{
kfree(jwt);
return strncmp(jwt->signature, hash_base64, bytes);
}
10 changes: 9 additions & 1 deletion jwt.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,17 @@ typedef struct jwt
char *aud;
u64 exp;

// data is the base64url encoded JSON header.payload part of the JWT
const char *data;
unsigned data_len;

const char *signature;
unsigned signature_len;

} jwt_t;

jwt_t *jwt_parse(const char *jwt, const char *secret);
jwt_t *jwt_parse(const char *jwt, const unsigned len);
int jwt_verify(jwt_t *jwt, const char *secret, const unsigned secret_len);
void jwt_free(jwt_t *jwt);

#endif
15 changes: 14 additions & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,23 @@ static int __init camblet_init(void)
}

// test jwt
jwt_t *jwt = jwt_parse("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.kGWDzjy0MXc1UiDVSZNAoFQMeVKBievVdGmTE1fOEXg", "no");
const char *token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.kGWDzjy0MXc1UiDVSZNAoFQMeVKBievVdGmTE1fOEXg";
jwt_t *jwt = jwt_parse(token, strlen(token));
if (jwt)
{
pr_info("jwt: alg=%s, typ=%s, iss=%s, sub=%s, aud=%s, exp=%llu", jwt->alg, jwt->typ, jwt->iss, jwt->sub, jwt->aud, jwt->exp);

const char *secret = "no";
int ret = jwt_verify(jwt, secret, strlen(secret));
if (ret == 0)
{
pr_info("jwt: verified");
}
else
{
pr_err("jwt: failed to verify");
}

jwt_free(jwt);
}
else
Expand Down
1 change: 1 addition & 0 deletions third-party/fastjson
Submodule fastjson added at 4088f3
6 changes: 3 additions & 3 deletions third-party/parson/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -2306,9 +2306,9 @@ int json_value_equals(const JSON_Value *a, const JSON_Value *b) {
}
}

JSON_Value_Type json_type(const JSON_Value *value) {
return json_value_get_type(value);
}
// JSON_Value_Type json_type(const JSON_Value *value) {
// return json_value_get_type(value);
// }

JSON_Object * json_object (const JSON_Value *value) {
return json_value_get_object(value);
Expand Down

0 comments on commit 8681486

Please sign in to comment.