diff --git a/src/sbbs3/js_cryptcon.c b/src/sbbs3/js_cryptcon.c index 91ef723b0294b368ec2e3e9504441b420e1c4dd6..4fe6b8a4b015d8264b8997129adbc5eb119e89b9 100644 --- a/src/sbbs3/js_cryptcon.c +++ b/src/sbbs3/js_cryptcon.c @@ -5,14 +5,11 @@ #include "sbbs.h" #include <cryptlib.h> #include "js_request.h" +#include "js_cryptcon.h" #include "ssl.h" #include "base64.h" -struct private_data { - CRYPT_CONTEXT ctx; -}; - -static JSClass js_cryptcon_class; +JSClass js_cryptcon_class; static const char* getprivate_failure = "line %d %s %s JS_GetPrivate failed"; // Helpers @@ -204,7 +201,7 @@ static void js_simple_asn1(unsigned char *data, size_t len, JSContext *cx, JSObj static void js_create_key_object(JSContext *cx, JSObject *parent) { - struct private_data* p; + struct js_cryptcon_private_data* p; jsrefcount rc; int status; int val; @@ -212,7 +209,7 @@ static void js_create_key_object(JSContext *cx, JSObject *parent) CRYPT_CERTIFICATE cert; // Just to hold the public key... unsigned char *certbuf; - if ((p=(struct private_data *)JS_GetPrivate(cx,parent))==NULL) + if ((p=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,parent))==NULL) return; rc = JS_SUSPENDREQUEST(cx); @@ -280,9 +277,9 @@ resume: static void js_finalize_cryptcon(JSContext *cx, JSObject *obj) { - struct private_data* p; + struct js_cryptcon_private_data* p; - if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) + if ((p=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,obj))==NULL) return; cryptDestroyContext(p->ctx); @@ -296,12 +293,12 @@ js_finalize_cryptcon(JSContext *cx, JSObject *obj) static JSBool js_generate_key(JSContext *cx, uintN argc, jsval *arglist) { - struct private_data* p; + struct js_cryptcon_private_data* p; JSObject *obj=JS_THIS_OBJECT(cx, arglist); jsrefcount rc; int status; - if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + if ((p=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx, getprivate_failure, WHERE); return JS_FALSE; } @@ -322,7 +319,7 @@ js_generate_key(JSContext *cx, uintN argc, jsval *arglist) static JSBool js_set_key(JSContext *cx, uintN argc, jsval *arglist) { - struct private_data* p; + struct js_cryptcon_private_data* p; JSObject *obj; jsval *argv; size_t len; @@ -341,7 +338,7 @@ js_set_key(JSContext *cx, uintN argc, jsval *arglist) return JS_FALSE; obj = JS_THIS_OBJECT(cx, arglist); - if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + if ((p=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,obj))==NULL) { free(key); JS_ReportError(cx, getprivate_failure, WHERE); return JS_FALSE; @@ -364,7 +361,7 @@ js_set_key(JSContext *cx, uintN argc, jsval *arglist) static JSBool js_derive_key(JSContext *cx, uintN argc, jsval *arglist) { - struct private_data* p; + struct js_cryptcon_private_data* p; JSObject *obj; jsval *argv; size_t len; @@ -389,7 +386,7 @@ js_derive_key(JSContext *cx, uintN argc, jsval *arglist) } obj = JS_THIS_OBJECT(cx, arglist); - if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + if ((p=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,obj))==NULL) { free(key); JS_ReportError(cx, getprivate_failure, WHERE); return JS_FALSE; @@ -412,7 +409,7 @@ js_derive_key(JSContext *cx, uintN argc, jsval *arglist) static JSBool js_do_encrption(JSContext *cx, uintN argc, jsval *arglist, int encrypt) { - struct private_data* p; + struct js_cryptcon_private_data* p; JSObject *obj; jsval *argv; size_t len; @@ -427,7 +424,7 @@ js_do_encrption(JSContext *cx, uintN argc, jsval *arglist, int encrypt) argv = JS_ARGV(cx, arglist); obj = JS_THIS_OBJECT(cx, arglist); - if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + if ((p=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx, getprivate_failure, WHERE); return JS_FALSE; } @@ -472,8 +469,8 @@ js_decrypt(JSContext *cx, uintN argc, jsval *arglist) static JSBool js_create_signature(JSContext *cx, uintN argc, jsval *arglist) { - struct private_data* p; - struct private_data* scp; + struct js_cryptcon_private_data* p; + struct js_cryptcon_private_data* scp; JSObject *sigCtx; JSObject *obj; jsval *argv; @@ -489,7 +486,7 @@ js_create_signature(JSContext *cx, uintN argc, jsval *arglist) argv = JS_ARGV(cx, arglist); obj = JS_THIS_OBJECT(cx, arglist); - if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + if ((p=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx, getprivate_failure, WHERE); return JS_FALSE; } @@ -497,7 +494,7 @@ js_create_signature(JSContext *cx, uintN argc, jsval *arglist) if (!JS_InstanceOf(cx, sigCtx, &js_cryptcon_class, NULL)) return JS_FALSE; HANDLE_PENDING(cx, NULL); - if ((scp=(struct private_data *)JS_GetPrivate(cx,sigCtx))==NULL) { + if ((scp=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,sigCtx))==NULL) { JS_ReportError(cx, getprivate_failure, WHERE); return JS_FALSE; } @@ -634,9 +631,9 @@ js_cryptcon_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp) { jsval idval; jsint tiny; - struct private_data* p; + struct js_cryptcon_private_data* p; - if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + if ((p=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx, getprivate_failure, WHERE); return JS_FALSE; } @@ -731,9 +728,9 @@ js_cryptcon_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { jsval idval; jsint tiny; - struct private_data* p; + struct js_cryptcon_private_data* p; - if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + if ((p=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,obj))==NULL) { return JS_TRUE; JS_ReportError(cx, getprivate_failure, WHERE); return JS_FALSE; @@ -846,7 +843,7 @@ static JSBool js_cryptcon_enumerate(JSContext *cx, JSObject *obj) return(js_cryptcon_resolve(cx, obj, JSID_VOID)); } -static JSClass js_cryptcon_class = { +JSClass js_cryptcon_class = { "CryptContext" /* name */ ,JSCLASS_HAS_PRIVATE /* flags */ ,JS_PropertyStub /* addProperty */ @@ -859,6 +856,29 @@ static JSClass js_cryptcon_class = { ,js_finalize_cryptcon /* finalize */ }; +JSObject* DLLCALL js_CreateCryptconObject(JSContext* cx, CRYPT_CONTEXT ctx) +{ + JSObject *obj; + struct js_cryptcon_private_data *p; + + obj=JS_NewObject(cx, &js_cryptcon_class, NULL, NULL); + + if((p=(struct js_cryptcon_private_data *)malloc(sizeof(struct js_cryptcon_private_data)))==NULL) { + JS_ReportError(cx,"malloc failed"); + return NULL; + } + memset(p,0,sizeof(struct js_cryptcon_private_data)); + p->ctx = ctx; + + if(!JS_SetPrivate(cx, obj, p)) { + JS_ReportError(cx,"JS_SetPrivate failed"); + return NULL; + } + js_create_key_object(cx, obj); + + return obj; +} + // Constructor static JSBool @@ -866,7 +886,7 @@ js_cryptcon_constructor(JSContext *cx, uintN argc, jsval *arglist) { JSObject *obj; jsval *argv=JS_ARGV(cx, arglist); - struct private_data *p; + struct js_cryptcon_private_data *p; jsrefcount rc; int status; int algo; @@ -881,11 +901,11 @@ js_cryptcon_constructor(JSContext *cx, uintN argc, jsval *arglist) if (!JS_ValueToInt32(cx,argv[0],&algo)) return JS_FALSE; - if((p=(struct private_data *)malloc(sizeof(struct private_data)))==NULL) { + if((p=(struct js_cryptcon_private_data *)malloc(sizeof(struct js_cryptcon_private_data)))==NULL) { JS_ReportError(cx,"malloc failed"); return(JS_FALSE); } - memset(p,0,sizeof(struct private_data)); + memset(p,0,sizeof(struct js_cryptcon_private_data)); if(!JS_SetPrivate(cx, obj, p)) { JS_ReportError(cx,"JS_SetPrivate failed"); diff --git a/src/sbbs3/js_cryptcon.h b/src/sbbs3/js_cryptcon.h new file mode 100644 index 0000000000000000000000000000000000000000..c9331176b70fdb409fddc77d7a528041b10f38f8 --- /dev/null +++ b/src/sbbs3/js_cryptcon.h @@ -0,0 +1,12 @@ +#ifndef _JS_CRYPTCON_H_ +#define _JS_CRYPTCON_H_ + +struct js_cryptcon_private_data { + CRYPT_CONTEXT ctx; +}; + +extern JSClass js_cryptcon_class; + +JSObject* DLLCALL js_CreateCryptconObject(JSContext* cx, CRYPT_CONTEXT ctx); + +#endif diff --git a/src/sbbs3/js_cryptkeyset.c b/src/sbbs3/js_cryptkeyset.c new file mode 100644 index 0000000000000000000000000000000000000000..14a4905b298199de772fa3d49802b20c90376589 --- /dev/null +++ b/src/sbbs3/js_cryptkeyset.c @@ -0,0 +1,446 @@ +/* $Id$ */ + +// Cyrptlib Keyset... + +#include "sbbs.h" +#include <cryptlib.h> +#include "js_request.h" +#include "js_cryptcon.h" +#include "ssl.h" + +struct private_data { + CRYPT_KEYSET ks; + char *name; +}; + +static JSClass js_cryptkeyset_class; +static const char* getprivate_failure = "line %d %s %s JS_GetPrivate failed"; + +// Helpers + +// Destructor + +static void +js_finalize_cryptkeyset(JSContext *cx, JSObject *obj) +{ + jsrefcount rc; + struct private_data* p; + + if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) + return; + + rc = JS_SUSPENDREQUEST(cx); + if (p->ks != CRYPT_UNUSED) + cryptKeysetClose(p->ks); + FREE_AND_NULL(p->name); + free(p); + JS_RESUMEREQUEST(cx, rc); + + JS_SetPrivate(cx, obj, NULL); +} + +// Methods + +static JSBool +js_add_private_key(JSContext *cx, uintN argc, jsval *arglist) +{ + struct private_data* p; + struct js_cryptcon_private_data* ctx; + jsval *argv=JS_ARGV(cx, arglist); + char* pw = NULL; + int status; + jsrefcount rc; + JSObject *key; + JSString *jspw; + JSObject *obj=JS_THIS_OBJECT(cx, arglist); + + if (!js_argc(cx, argc, 2)) + return JS_FALSE; + if (argc > 2) { + JS_ReportError(cx, "Too many arguments"); + return JS_FALSE; + } + key = JSVAL_TO_OBJECT(argv[0]); + if (!JS_InstanceOf(cx, key, &js_cryptcon_class, NULL)) { + JS_ReportError(cx, "Invalid CryptContext"); + return JS_FALSE; + } + + argv = JS_ARGV(cx, arglist); + if ((jspw = JS_ValueToString(cx, argv[1])) == NULL) { + JS_ReportError(cx, "Invalid password"); + return JS_FALSE; + } + + if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + JS_ReportError(cx, getprivate_failure, WHERE); + return JS_FALSE; + } + + if ((ctx=(struct js_cryptcon_private_data *)JS_GetPrivate(cx,key))==NULL) { + JS_ReportError(cx, getprivate_failure, WHERE); + return JS_FALSE; + } + + JSSTRING_TO_MSTRING(cx, jspw, pw, NULL); + HANDLE_PENDING(cx, pw); + rc = JS_SUSPENDREQUEST(cx); + status = cryptAddPrivateKey(p->ks, ctx->ctx, pw); + free(pw); + JS_RESUMEREQUEST(cx, rc); + + if (cryptStatusError(status)) { + JS_ReportError(cx, "Error %d calling cryptAddPrivateKey()\n", status); + return JS_FALSE; + } + return JS_TRUE; +} + +static JSBool +js_close(JSContext *cx, uintN argc, jsval *arglist) +{ + struct private_data* p; + JSObject *obj=JS_THIS_OBJECT(cx, arglist); + jsrefcount rc; + int status; + + if (argc) { + JS_ReportError(cx, "close() takes no arguments"); + return JS_FALSE; + } + if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + JS_ReportError(cx, getprivate_failure, WHERE); + return JS_FALSE; + } + if (p->ks == CRYPT_UNUSED) { + JS_ReportError(cx, "already closed"); + return JS_FALSE; + } + rc = JS_SUSPENDREQUEST(cx); + status = cryptKeysetClose(p->ks); + JS_RESUMEREQUEST(cx, rc); + if (cryptStatusError(status)) { + JS_ReportError(cx, "Error %d calling cryptKeysetClose()\n", status); + return JS_FALSE; + } + + return JS_TRUE; +} + +static JSBool +js_delete_key(JSContext *cx, uintN argc, jsval *arglist) +{ + struct private_data* p; + jsval *argv=JS_ARGV(cx, arglist); + int status; + jsrefcount rc; + char* label = NULL; + JSString *jslabel; + JSObject *obj=JS_THIS_OBJECT(cx, arglist); + + if (!js_argc(cx, argc, 1)) + return JS_FALSE; + if (argc > 1) { + JS_ReportError(cx, "Too many arguments"); + return JS_FALSE; + } + if ((jslabel = JS_ValueToString(cx, argv[0])) == NULL) { + JS_ReportError(cx, "Invalid label"); + return JS_FALSE; + } + + if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + JS_ReportError(cx, getprivate_failure, WHERE); + return JS_FALSE; + } + + JSSTRING_TO_MSTRING(cx, jslabel, label, NULL); + HANDLE_PENDING(cx, label); + rc = JS_SUSPENDREQUEST(cx); + status = cryptDeleteKey(p->ks, CRYPT_KEYID_NAME, label); +fprintf(stderr, "cryptDeleteKey(%s) = %d\n", label, status); + free(label); + JS_RESUMEREQUEST(cx, rc); + if (cryptStatusError(status)) { + JS_ReportError(cx, "Error %d calling cryptDeleteKey()\n", status); + return JS_FALSE; + } + return JS_TRUE; +} + +static JSBool +js_get_private_key(JSContext *cx, uintN argc, jsval *arglist) +{ + struct private_data* p; + jsval *argv=JS_ARGV(cx, arglist); + int status; + jsrefcount rc; + JSObject *key; + char* pw = NULL; + char* label = NULL; + JSString *jspw; + JSString *jslabel; + CRYPT_CONTEXT ctx; + JSObject *obj=JS_THIS_OBJECT(cx, arglist); + + if (!js_argc(cx, argc, 2)) + return JS_FALSE; + if (argc > 2) { + JS_ReportError(cx, "Too many arguments"); + return JS_FALSE; + } + if ((jslabel = JS_ValueToString(cx, argv[0])) == NULL) { + JS_ReportError(cx, "Invalid label"); + return JS_FALSE; + } + if ((jspw = JS_ValueToString(cx, argv[1])) == NULL) { + JS_ReportError(cx, "Invalid password"); + return JS_FALSE; + } + + if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + JS_ReportError(cx, getprivate_failure, WHERE); + return JS_FALSE; + } + + JSSTRING_TO_MSTRING(cx, jslabel, label, NULL); + HANDLE_PENDING(cx, label); + JSSTRING_TO_MSTRING(cx, jspw, pw, NULL); + if (JS_IsExceptionPending(cx)) { + FREE_AND_NULL(label); + FREE_AND_NULL(pw); + return JS_FALSE; + } + rc = JS_SUSPENDREQUEST(cx); + status = cryptGetPrivateKey(p->ks, &ctx, CRYPT_KEYID_NAME, label, pw); + free(label); + free(pw); + JS_RESUMEREQUEST(cx, rc); + if (cryptStatusError(status)) { + JS_ReportError(cx, "Error %d calling cryptGetPrivateKey()\n", status); + return JS_FALSE; + } + key = js_CreateCryptconObject(cx, ctx); + if (key == NULL) + return JS_FALSE; + JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(key)); + + return JS_TRUE; +} + +// Properties + +static JSBool +js_cryptkeyset_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + jsval idval; + jsint tiny; + struct private_data* p; + + if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + return JS_TRUE; + JS_ReportError(cx, getprivate_failure, WHERE); + return JS_FALSE; + } + + JS_IdToValue(cx, id, &idval); + tiny = JSVAL_TO_INT(idval); + + switch (tiny) { + } + return JS_TRUE; +} + +static JSBool +js_cryptkeyset_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp) +{ + jsval idval; + jsint tiny; + struct private_data* p; + + if ((p=(struct private_data *)JS_GetPrivate(cx,obj))==NULL) { + JS_ReportError(cx, getprivate_failure, WHERE); + return JS_FALSE; + } + + JS_IdToValue(cx, id, &idval); + tiny = JSVAL_TO_INT(idval); + + switch (tiny) { + } + return JS_TRUE; +} + + +#ifdef BUILD_JSDOCS +static char* cryptkeyset_prop_desc[] = { + "Keyopt constant (CryptKeyset.KEYOPT.XXX):<ul class=\"showList\">\n" + "<li>CryptKeyset.KEYOPT.NONE</li>\n" + "<li>CryptKeyset.KEYOPT.READONLY</li>\n" + "<li>CryptKeyset.KEYOPT.CREATE</li>\n" + ,NULL +}; +#endif + +static jsSyncPropertySpec js_cryptkeyset_properties[] = { +/* name ,tinyid ,flags, ver */ + {0} +}; + +static jsSyncMethodSpec js_cryptkeyset_functions[] = { + {"add_private_key", js_add_private_key, 0, JSTYPE_VOID, "CryptContext, password" + ,JSDOCSTR("Add a private key to the keyset, encrypting it with <password>.") + ,316 + }, + {"close", js_close, 0, JSTYPE_VOID, "" + ,JSDOCSTR("Close the keyset.") + ,316 + }, + {"delete_key", js_delete_key, 0, JSTYPE_VOID, "label" + ,JSDOCSTR("Delete the key with <label> from the keyset.") + ,316 + }, + {"get_private_key", js_get_private_key, 0, JSTYPE_OBJECT, "label, password" + ,JSDOCSTR("Returns a CryptContext from the private key with <label> encrypted with <password>.") + ,316 + }, + {0} +}; + +static JSBool js_cryptkeyset_resolve(JSContext *cx, JSObject *obj, jsid id) +{ + char* name=NULL; + JSBool ret; + + if(id != JSID_VOID && id != JSID_EMPTY) { + jsval idval; + + JS_IdToValue(cx, id, &idval); + if(JSVAL_IS_STRING(idval)) { + JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(idval), name, NULL); + HANDLE_PENDING(cx, name); + } + } + + ret=js_SyncResolve(cx, obj, name, js_cryptkeyset_properties, js_cryptkeyset_functions, NULL, 0); + if(name) + free(name); + return ret; +} + +static JSBool js_cryptkeyset_enumerate(JSContext *cx, JSObject *obj) +{ + return(js_cryptkeyset_resolve(cx, obj, JSID_VOID)); +} + +static JSClass js_cryptkeyset_class = { + "CryptKeyset" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_cryptkeyset_get /* getProperty */ + ,js_cryptkeyset_set /* setProperty */ + ,js_cryptkeyset_enumerate /* enumerate */ + ,js_cryptkeyset_resolve /* resolve */ + ,JS_ConvertStub /* convert */ + ,js_finalize_cryptkeyset /* finalize */ +}; + +// Constructor + +static JSBool +js_cryptkeyset_constructor(JSContext *cx, uintN argc, jsval *arglist) +{ + JSObject *obj; + jsval *argv=JS_ARGV(cx, arglist); + struct private_data *p; + jsrefcount rc; + int status; + int opts = CRYPT_KEYOPT_NONE; + JSString *fn; + size_t fnslen; + + do_cryptInit(); + obj=JS_NewObject(cx, &js_cryptkeyset_class, NULL, NULL); + JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj)); + if(argc < 1 || argc > 2) { + JS_ReportError(cx, "Incorrect number of arguments to CryptKeyset constructor. Got %d, expected 1 or 2.", argc); + return JS_FALSE; + } + if ((fn = JS_ValueToString(cx, argv[0])) == NULL) + return JS_FALSE; + if (argc == 2) + if (!JS_ValueToInt32(cx,argv[1],&opts)) + return JS_FALSE; + + if((p=(struct private_data *)malloc(sizeof(struct private_data)))==NULL) { + JS_ReportError(cx,"malloc failed"); + return(JS_FALSE); + } + memset(p,0,sizeof(struct private_data)); + + if(!JS_SetPrivate(cx, obj, p)) { + JS_ReportError(cx,"JS_SetPrivate failed"); + return(JS_FALSE); + } + + JSSTRING_TO_MSTRING(cx, fn, p->name, &fnslen); + if (p->name == NULL) { + free(p); + return JS_FALSE; + } + rc = JS_SUSPENDREQUEST(cx); +fprintf(stderr, "Name: %s, opts: %02x\n", p->name, opts); + status = cryptKeysetOpen(&p->ks, CRYPT_UNUSED, CRYPT_KEYSET_FILE, p->name, opts); + JS_RESUMEREQUEST(cx, rc); + if (cryptStatusError(status)) { + JS_ReportError(cx, "CryptLib error %d", status); + FREE_AND_NULL(p->name); + free(p); + return JS_FALSE; + } + +#ifdef BUILD_JSDOCS + js_DescribeSyncObject(cx,obj,"Class used for storing CryptContext keys",31601); + js_DescribeSyncConstructor(cx,obj,"To create a new CryptKeyset object: " + "var c = new CryptKeyset('<i>filename</i>' [ <i>opts = CryptKeyset.KEYOPT.NONE</i> ])</tt><br>" + "where <i>filename</i> is the name of the file to create, and <i>opts</i>" + "is a value from from CryptKeyset.KEYOPT" + ); + js_CreateArrayOfStrings(cx, obj, "_property_desc_list", cryptkeyset_prop_desc, JSPROP_READONLY); +#endif + + return(JS_TRUE); +} + +JSObject* DLLCALL js_CreateCryptKeysetClass(JSContext* cx, JSObject* parent) +{ + JSObject* cksobj; + JSObject* constructor; + JSObject* opts; + jsval val; + + cksobj = JS_InitClass(cx, parent, NULL + ,&js_cryptkeyset_class + ,js_cryptkeyset_constructor + ,1 /* number of constructor args */ + ,NULL /* props, specified in constructor */ + ,NULL /* funcs, specified in constructor */ + ,NULL, NULL); + + if(JS_GetProperty(cx, parent, js_cryptkeyset_class.name, &val) && !JSVAL_NULL_OR_VOID(val)) { + JS_ValueToObject(cx,val,&constructor); + opts = JS_DefineObject(cx, constructor, "KEYOPT", NULL, NULL, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY); + if(opts != NULL) { + JS_DefineProperty(cx, opts, "NONE", INT_TO_JSVAL(CRYPT_KEYOPT_NONE), NULL, NULL + , JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY); + JS_DefineProperty(cx, opts, "READONLY", INT_TO_JSVAL(CRYPT_KEYOPT_READONLY), NULL, NULL + , JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY); + JS_DefineProperty(cx, opts, "CREATE", INT_TO_JSVAL(CRYPT_KEYOPT_CREATE), NULL, NULL + , JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY); + JS_DeepFreezeObject(cx, opts); + } + } + + return(cksobj); +} diff --git a/src/sbbs3/jsdoor.c b/src/sbbs3/jsdoor.c index 7ee36ec7b6a77102fd12ea65cfe30c29e5dba7be..b5d656355d77e754b6dbf42b3e51b258e82e8e80 100644 --- a/src/sbbs3/jsdoor.c +++ b/src/sbbs3/jsdoor.c @@ -254,6 +254,10 @@ BOOL DLLCALL js_CreateCommonObjects(JSContext* js_cx if(js_CreateCryptContextClass(js_cx, *glob)==NULL) break; + /* CryptKeyset Class */ + if(js_CreateCryptKeysetClass(js_cx, *glob)==NULL) + break; + success=TRUE; } while(0); diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 267b457f5355ddca89cc6db7748573154d092ae8..8712a440ac21d482931a8805cf35a0845194a29f 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -1366,6 +1366,10 @@ extern "C" BOOL DLLCALL js_CreateCommonObjects(JSContext* js_cx if(js_CreateCryptContextClass(js_cx, *glob)==NULL) break; + /* CryptKeyset Class */ + if(js_CreateCryptKeysetClass(js_cx, *glob)==NULL) + break; + /* Area Objects */ if(!js_CreateUserObjects(js_cx, *glob, cfg, /* user: */NULL, client, /* html_index_fname: */NULL, /* subscan: */NULL)) break; diff --git a/src/sbbs3/objects.mk b/src/sbbs3/objects.mk index 5b20a1c0afcae090ebd35c63996aaa27e5395f22..2aaffaf5f7ceae8162799e57d48ef85714f8ca22 100644 --- a/src/sbbs3/objects.mk +++ b/src/sbbs3/objects.mk @@ -46,6 +46,7 @@ OBJS = $(MTOBJODIR)$(DIRSEP)ansiterm$(OFILE) \ $(MTOBJODIR)$(DIRSEP)js_com$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_console$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_cryptcon$(OFILE)\ + $(MTOBJODIR)$(DIRSEP)js_cryptkeyset$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_file$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_file_area$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_global$(OFILE)\ diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 4c57d3c6ea3b4fd5b1824e69027eb4ceec47a103..a2d11d4a79542c3d80a6167a49836c908b7b283b 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -1334,6 +1334,9 @@ extern "C" { /* js_cryptcon.c */ DLLEXPORT JSObject* DLLCALL js_CreateCryptContextClass(JSContext* cx, JSObject* parent); + /* js_cryptkeyset.c */ + DLLEXPORT JSObject* DLLCALL js_CreateCryptKeysetClass(JSContext* cx, JSObject* parent); + #endif /* str_util.c */ diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c index 9cfec055f916d39b72fec07bfb9116ba7baa0b94..da2154f5d70d30381b20ec2beb1e84a84b2dd1ff 100644 --- a/src/sbbs3/services.c +++ b/src/sbbs3/services.c @@ -803,6 +803,10 @@ js_initcx(JSRuntime* js_runtime, SOCKET sock, service_client_t* service_client, if(js_CreateCryptContextClass(js_cx, *glob)==NULL) break; + /* CryptKeyset Class */ + if(js_CreateCryptKeysetClass(js_cx, *glob)==NULL) + break; + /* user-specific objects */ if(!js_CreateUserObjects(js_cx, *glob, &scfg, /*user: */NULL, service_client->client, NULL, service_client->subscan)) break;