diff --git a/cli/build/src/jsbridge.o b/cli/build/src/jsbridge.o index 6d55538..3839f88 100644 Binary files a/cli/build/src/jsbridge.o and b/cli/build/src/jsbridge.o differ diff --git a/cli/build/src/main.o b/cli/build/src/main.o index 5378373..efec44f 100644 Binary files a/cli/build/src/main.o and b/cli/build/src/main.o differ diff --git a/cli/src/jsbridge.c b/cli/src/jsbridge.c index e72b51b..42316c7 100644 --- a/cli/src/jsbridge.c +++ b/cli/src/jsbridge.c @@ -484,6 +484,11 @@ char *jsbridge_totp(const char *seed_b32) { return out; } +int jsbridge_load(const char *filename) { + if (!ctx) return -1; + return load_js_file(ctx, filename); +} + char *jsbridge_eval(const char *code) { if (!ctx) return NULL; JSValue val = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_GLOBAL); diff --git a/cli/src/jsbridge.h b/cli/src/jsbridge.h index b896754..072170a 100644 --- a/cli/src/jsbridge.h +++ b/cli/src/jsbridge.h @@ -39,4 +39,7 @@ char *jsbridge_totp(const char *seed_b32); /* Evaluate JS code and return result as string (caller frees). NULL on error. */ char *jsbridge_eval(const char *code); +/* Load and evaluate a JS file. Returns 0 on success. */ +int jsbridge_load(const char *filename); + #endif diff --git a/cli/src/main.c b/cli/src/main.c index 3f55c17..8dc46e5 100644 --- a/cli/src/main.c +++ b/cli/src/main.c @@ -179,37 +179,24 @@ int main(int argc, char **argv) { if (strcmp(cmd, "test-crypto") == 0) { return cmd_test_crypto(); } if (strcmp(cmd, "test-roundtrip") == 0) { if (jsbridge_init() != 0) { fprintf(stderr, "error: crypto init failed\n"); return 1; } - char *r = jsbridge_eval( - "var R = [];" - "function t(kb, label, pt) {" - " var k = new Uint8Array(kb);" - " var d = kb.length + 'B key, label=' + label;" - " try {" - " var ct = vault1984.crypto.encrypt_field(k, label, pt);" - " var p2 = vault1984.crypto.decrypt_field(k, label, ct);" - " R.push(d + ': ' + (p2 === pt ? 'PASS' : 'FAIL got=' + p2));" - " } catch(e) { R.push(d + ': ERROR ' + e.message); }" - "}" - /* 8-byte key */ - "t([1,2,3,4,5,6,7,8], 'username', 'johanj');" - /* 16-byte key (L2) */ - "t([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], 'password', 's3cret!');" - "t([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], 'totp', 'JBSWY3DPEHPK3PXP');" - "t([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], 'Number', '5452120017212208');" - /* 32-byte key (L3) */ - "t([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32], 'passport', 'NL12345678');" - "t([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32], 'CVV', '755');" - /* wrong key must fail */ - "var k1=new Uint8Array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);" - "var k2=new Uint8Array([99,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);" - "try{var c=vault1984.crypto.encrypt_field(k1,'x','s');vault1984.crypto.decrypt_field(k2,'x',c);R.push('wrong-key: FAIL')}catch(e){R.push('wrong-key rejection: PASS')}" - /* wrong label must fail */ - "try{var c2=vault1984.crypto.encrypt_field(k1,'a','s');vault1984.crypto.decrypt_field(k1,'b',c2);R.push('wrong-label: FAIL')}catch(e){R.push('wrong-label rejection: PASS')}" - "R.join('\\n');" - ); + if (jsbridge_load("crypto/test_crypto.js") != 0) { + fprintf(stderr, "error: cannot load test_crypto.js\n"); + jsbridge_cleanup(); + return 1; + } + char *r = jsbridge_eval("globalThis._v1984_test_result"); + if (r) { printf("%s\n", r); } + int ok = (r && strstr(r, "FAILED") == NULL); + free(r); + jsbridge_cleanup(); + return ok ? 0 : 1; + } + if (strcmp(cmd, "eval") == 0 && argc > 2) { + if (jsbridge_init() != 0) { fprintf(stderr, "error: crypto init failed\n"); return 1; } + char *r = jsbridge_eval(argv[2]); if (r) { printf("%s\n", r); free(r); } jsbridge_cleanup(); - return (r && strstr(r, "FAIL") == NULL && strstr(r, "ERROR") == NULL) ? 0 : 1; + return r ? 0 : 1; } if (strcmp(cmd, "test-totp") == 0) { if (argc < 3) { @@ -307,6 +294,11 @@ int main(int argc, char **argv) { snprintf(cfg.agent_name, sizeof(cfg.agent_name), "%s", agent_name); memcpy(cfg.l2_key, l2_key, 16); + /* Debug: show L2 key for verification — REMOVE BEFORE RELEASE */ + fprintf(stderr, "L2 key: ["); + for (int i = 0; i < 16; i++) fprintf(stderr, "%s%d", i?",":"", cfg.l2_key[i]); + fprintf(stderr, "]\n"); + /* L1 = first 8 bytes of L2 key, used as Bearer auth */ char bearer[32]; get_bearer(&cfg, bearer, sizeof(bearer)); @@ -406,7 +398,7 @@ int main(int argc, char **argv) { const char *value = cJSON_GetStringValue(cJSON_GetObjectItem(field, "value")); cJSON *tier_j = cJSON_GetObjectItem(field, "tier"); cJSON *l2_j = cJSON_GetObjectItem(field, "l2"); - int tier_val = tier_j ? tier_j->valueint : (l2_j && cJSON_IsTrue(l2_j) ? 2 : 1); + int tier_val = tier_j ? tier_j->valueint : (l2_j && cJSON_IsTrue(l2_j) ? 3 : 1); if (!label) continue; if (tier_val >= 3) { diff --git a/cli/vault1984-cli b/cli/vault1984-cli index 61ef6fc..8dbad40 100755 Binary files a/cli/vault1984-cli and b/cli/vault1984-cli differ diff --git a/crypto/test_crypto.js b/crypto/test_crypto.js new file mode 100644 index 0000000..a6075a2 --- /dev/null +++ b/crypto/test_crypto.js @@ -0,0 +1,251 @@ +/* + * vault1984 — crypto test suite + * Runs in both QuickJS (CLI) and browser. + * + * CLI: vault1984-cli test-roundtrip + * Web: open browser console, paste: fetch('/app/test_crypto.js').then(r=>r.text()).then(eval) + * or load as