#include "tlscontext.js.h" #include "mem.h" #include "task.h" #include "tls.h" #include #include #include static JSClassID _classId; static int _count; typedef struct _tf_tls_context_t { tf_tls_context_t* context; tf_task_t* task; JSValue object; } tf_tls_context_t; static JSValue _tls_context_set_certificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _tls_context_set_private_key(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _tls_context_add_trusted_certificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _tls_context_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static void _tls_context_finalizer(JSRuntime *runtime, JSValue value); JSValue _tls_context_set_certificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_tls_context_t* tls = JS_GetOpaque(this_val, _classId); const char* value = JS_ToCString(context, argv[0]); tf_tls_context_set_certificate(tls->context, value); JS_FreeCString(context, value); return JS_UNDEFINED; } JSValue _tls_context_set_private_key(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_tls_context_t* tls = JS_GetOpaque(this_val, _classId); const char* value = JS_ToCString(context, argv[0]); tf_tls_context_set_private_key(tls->context, value); JS_FreeCString(context, value); return JS_UNDEFINED; } JSValue _tls_context_add_trusted_certificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_tls_context_t* tls = JS_GetOpaque(this_val, _classId); const char* value = JS_ToCString(context, argv[0]); tf_tls_context_add_trusted_certificate(tls->context, value); JS_FreeCString(context, value); return JS_UNDEFINED; } JSValue tf_tls_context_register(JSContext* context) { JS_NewClassID(&_classId); JSClassDef def = { .class_name = "TlsContext", .finalizer = _tls_context_finalizer, }; if (JS_NewClass(JS_GetRuntime(context), _classId, &def) != 0) { fprintf(stderr, "Failed to register TlsContext.\n"); } return JS_NewCFunction2(context, _tls_context_create, "TlsContext", 0, JS_CFUNC_constructor, 0); } tf_tls_context_t* tf_tls_context_get(JSValue value) { tf_tls_context_t* tls = JS_GetOpaque(value, _classId); return tls ? tls->context : NULL; } int tf_tls_context_get_count() { return _count; } JSValue _tls_context_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_tls_context_t* tls = tf_malloc(sizeof(tf_tls_context_t)); memset(tls, 0, sizeof(*tls)); ++_count; tls->object = JS_NewObjectClass(context, _classId); JS_SetOpaque(tls->object, tls); JS_SetPropertyStr(context, tls->object, "setCertificate", JS_NewCFunction(context, _tls_context_set_certificate, "setCertificate", 1)); JS_SetPropertyStr(context, tls->object, "setPrivateKey", JS_NewCFunction(context, _tls_context_set_private_key, "setPrivateKey", 1)); JS_SetPropertyStr(context, tls->object, "addTrustedCertificate", JS_NewCFunction(context, _tls_context_add_trusted_certificate, "addTrustedCertificate", 1)); tls->context = tf_tls_context_create(); tls->task = tf_task_get(context); return tls->object; } void _tls_context_finalizer(JSRuntime *runtime, JSValue value) { tf_tls_context_t* tls = JS_GetOpaque(value, _classId); if (tls->context) { tf_tls_context_destroy(tls->context); tls->context = NULL; } --_count; tf_free(tls); }