forked from cory/tildefriends
		
	Expose bip39 to script, and fix some things around base64 so that I can round trip it properly.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4729 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		| @@ -45,12 +45,12 @@ function readSession(session) { | |||||||
| 	let jwt_parts = session?.split('.'); | 	let jwt_parts = session?.split('.'); | ||||||
| 	if (jwt_parts?.length === 3) { | 	if (jwt_parts?.length === 3) { | ||||||
| 		let [header, payload, signature] = jwt_parts; | 		let [header, payload, signature] = jwt_parts; | ||||||
| 		header = JSON.parse(base64Decode(unb64url(header))); | 		header = JSON.parse(utf8Decode(base64Decode(unb64url(header)))); | ||||||
| 		if (header.typ === 'JWT' && header.alg === 'HS256') { | 		if (header.typ === 'JWT' && header.alg === 'HS256') { | ||||||
| 			signature = unb64url(signature); | 			signature = unb64url(signature); | ||||||
| 			let id = ssb.getIdentities(':auth'); | 			let id = ssb.getIdentities(':auth'); | ||||||
| 			if (id?.length && ssb.hmacsha256verify(id[0], payload, signature)) { | 			if (id?.length && ssb.hmacsha256verify(id[0], payload, signature)) { | ||||||
| 				let result = JSON.parse(base64Decode(unb64url(payload))); | 				let result = JSON.parse(utf8Decode(base64Decode(unb64url(payload)))); | ||||||
| 				let now = new Date().valueOf() | 				let now = new Date().valueOf() | ||||||
| 				if (now < result.exp) { | 				if (now < result.exp) { | ||||||
| 					print(`JWT valid for another ${(result.exp - now) / 1000} seconds.`); | 					print(`JWT valid for another ${(result.exp - now) / 1000} seconds.`); | ||||||
|   | |||||||
| @@ -653,7 +653,7 @@ static void _test_b64(const tf_test_options_t* options) | |||||||
| 	fprintf(file, | 	fprintf(file, | ||||||
| 		"'use strict';\n" | 		"'use strict';\n" | ||||||
| 		"print(base64Encode('hello'));\n" | 		"print(base64Encode('hello'));\n" | ||||||
| 		"let x = base64Decode(base64Encode('hello'));\n" | 		"let x = utf8Decode(base64Decode(base64Encode('hello')));\n" | ||||||
| 		"if (x !== 'hello') {\n" | 		"if (x !== 'hello') {\n" | ||||||
| 		"	print(x);\n" | 		"	print(x);\n" | ||||||
| 		"	exit(1);\n" | 		"	exit(1);\n" | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "util.js.h" | #include "util.js.h" | ||||||
|  |  | ||||||
|  | #include "bip39.h" | ||||||
| #include "log.h" | #include "log.h" | ||||||
| #include "mem.h" | #include "mem.h" | ||||||
| #include "task.h" | #include "task.h" | ||||||
| @@ -71,8 +72,20 @@ JSValue tf_util_utf8_decode(JSContext* context, JSValue value) | |||||||
| static JSValue _util_base64_encode(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | static JSValue _util_base64_encode(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||||
| { | { | ||||||
| 	JSValue result = JS_UNDEFINED; | 	JSValue result = JS_UNDEFINED; | ||||||
|  | 	JSValue buffer = JS_UNDEFINED; | ||||||
| 	size_t length = 0; | 	size_t length = 0; | ||||||
| 	uint8_t* array = tf_util_try_get_array_buffer(context, &length, argv[0]); | 	uint8_t* array = tf_util_try_get_array_buffer(context, &length, argv[0]); | ||||||
|  | 	if (!array) | ||||||
|  | 	{ | ||||||
|  | 		size_t offset; | ||||||
|  | 		size_t element_size; | ||||||
|  | 		buffer = tf_util_try_get_typed_array_buffer(context, argv[0], &offset, &length, &element_size); | ||||||
|  | 		if (!JS_IsException(buffer)) | ||||||
|  | 		{ | ||||||
|  | 			array = tf_util_try_get_array_buffer(context, &length, buffer); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (array) | 	if (array) | ||||||
| 	{ | 	{ | ||||||
| 		char* encoded = tf_malloc(length * 4); | 		char* encoded = tf_malloc(length * 4); | ||||||
| @@ -95,6 +108,7 @@ static JSValue _util_base64_encode(JSContext* context, JSValueConst this_val, in | |||||||
| 		tf_free(encoded); | 		tf_free(encoded); | ||||||
| 		JS_FreeCString(context, value); | 		JS_FreeCString(context, value); | ||||||
| 	} | 	} | ||||||
|  | 	JS_FreeValue(context, buffer); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -103,19 +117,58 @@ static JSValue _util_base64_decode(JSContext* context, JSValueConst this_val, in | |||||||
| 	JSValue result = JS_UNDEFINED; | 	JSValue result = JS_UNDEFINED; | ||||||
| 	size_t length = 0; | 	size_t length = 0; | ||||||
| 	const char* value = JS_ToCStringLen(context, &length, argv[0]); | 	const char* value = JS_ToCStringLen(context, &length, argv[0]); | ||||||
| 	uint8_t* encoded = tf_malloc(length); | 	uint8_t* decoded = tf_malloc(length); | ||||||
|  |  | ||||||
| 	int r = tf_base64_decode(value, length, encoded, length); | 	int r = tf_base64_decode(value, length, decoded, length); | ||||||
| 	if (r >= 0) | 	if (r >= 0) | ||||||
| 	{ | 	{ | ||||||
| 		result = JS_NewStringLen(context, (const char*)encoded, r); | 		result = tf_util_new_uint8_array(context, decoded, r); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tf_free(encoded); | 	tf_free(decoded); | ||||||
| 	JS_FreeCString(context, value); | 	JS_FreeCString(context, value); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static JSValue _util_bip39_words(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||||
|  | { | ||||||
|  | 	JSValue result = JS_UNDEFINED; | ||||||
|  | 	JSValue buffer = JS_UNDEFINED; | ||||||
|  | 	size_t length; | ||||||
|  | 	uint8_t* array = tf_util_try_get_array_buffer(context, &length, argv[0]); | ||||||
|  | 	if (!array) | ||||||
|  | 	{ | ||||||
|  | 		size_t offset; | ||||||
|  | 		size_t element_size; | ||||||
|  | 		buffer = tf_util_try_get_typed_array_buffer(context, argv[0], &offset, &length, &element_size); | ||||||
|  | 		if (!JS_IsException(buffer)) | ||||||
|  | 		{ | ||||||
|  | 			array = tf_util_try_get_array_buffer(context, &length, buffer); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	char words[2048] = ""; | ||||||
|  | 	if (array && tf_bip39_bytes_to_words(array, length, words, sizeof(words))) | ||||||
|  | 	{ | ||||||
|  | 		result = JS_NewString(context, words); | ||||||
|  | 	} | ||||||
|  | 	JS_FreeValue(context, buffer); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static JSValue _util_bip39_bytes(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||||
|  | { | ||||||
|  | 	const char* words = JS_ToCString(context, argv[0]); | ||||||
|  | 	uint8_t bytes[33] = { 0 }; | ||||||
|  | 	bool success = tf_bip39_words_to_bytes(words, bytes, sizeof(bytes)); | ||||||
|  | 	JS_FreeCString(context, words); | ||||||
|  | 	if (success) | ||||||
|  | 	{ | ||||||
|  | 		return tf_util_new_uint8_array(context, bytes, sizeof(bytes)); | ||||||
|  | 	} | ||||||
|  | 	return JS_UNDEFINED; | ||||||
|  | } | ||||||
|  |  | ||||||
| uint8_t* tf_util_try_get_array_buffer(JSContext* context, size_t* psize, JSValueConst obj) | uint8_t* tf_util_try_get_array_buffer(JSContext* context, size_t* psize, JSValueConst obj) | ||||||
| { | { | ||||||
| 	uint8_t* result = JS_GetArrayBuffer(context, psize, obj); | 	uint8_t* result = JS_GetArrayBuffer(context, psize, obj); | ||||||
| @@ -434,6 +487,8 @@ void tf_util_register(JSContext* context) | |||||||
| 	JS_SetPropertyStr(context, global, "utf8Encode", JS_NewCFunction(context, _util_utf8_encode, "utf8Encode", 1)); | 	JS_SetPropertyStr(context, global, "utf8Encode", JS_NewCFunction(context, _util_utf8_encode, "utf8Encode", 1)); | ||||||
| 	JS_SetPropertyStr(context, global, "base64Decode", JS_NewCFunction(context, _util_base64_decode, "base64Decode", 1)); | 	JS_SetPropertyStr(context, global, "base64Decode", JS_NewCFunction(context, _util_base64_decode, "base64Decode", 1)); | ||||||
| 	JS_SetPropertyStr(context, global, "base64Encode", JS_NewCFunction(context, _util_base64_encode, "base64Encode", 1)); | 	JS_SetPropertyStr(context, global, "base64Encode", JS_NewCFunction(context, _util_base64_encode, "base64Encode", 1)); | ||||||
|  | 	JS_SetPropertyStr(context, global, "bip39Words", JS_NewCFunction(context, _util_bip39_words, "bip39Words", 1)); | ||||||
|  | 	JS_SetPropertyStr(context, global, "bip39Bytes", JS_NewCFunction(context, _util_bip39_bytes, "bip39Bytes", 1)); | ||||||
| 	JS_SetPropertyStr(context, global, "print", JS_NewCFunction(context, _util_print, "print", 1)); | 	JS_SetPropertyStr(context, global, "print", JS_NewCFunction(context, _util_print, "print", 1)); | ||||||
| 	JS_SetPropertyStr(context, global, "setTimeout", JS_NewCFunction(context, _util_setTimeout, "setTimeout", 2)); | 	JS_SetPropertyStr(context, global, "setTimeout", JS_NewCFunction(context, _util_setTimeout, "setTimeout", 2)); | ||||||
| 	JS_SetPropertyStr(context, global, "parseHttpRequest", JS_NewCFunction(context, _util_parseHttpRequest, "parseHttpRequest", 2)); | 	JS_SetPropertyStr(context, global, "parseHttpRequest", JS_NewCFunction(context, _util_parseHttpRequest, "parseHttpRequest", 2)); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user