Index: build/tcl/Makefile ================================================================== --- build/tcl/Makefile +++ build/tcl/Makefile @@ -1,12 +1,16 @@ all: ssh-agent-noasync.js ssh-agent-noasync.js: ../chrome/ssh-agent.js - cc -Dawait='' -Dasync='' -nostdinc -C -E -x c ../chrome/ssh-agent.js -o - | grep -v '^# ' > ssh-agent-noasync.js.new + $(CC) -Dawait='' -Dasync='' -nostdinc -C -E -x c ../chrome/ssh-agent.js -o - | grep -v '^# ' > ssh-agent-noasync.js.new mv ssh-agent-noasync.js.new ssh-agent-noasync.js +softokn3-pkcs11.so: softokn3-pkcs11.c + $(CC) -fPIC -Wall -shared -o softokn3-pkcs11.so softokn3-pkcs11.c + clean: rm -f ssh-agent-noasync.js.new ssh-agent-noasync.js + rm -f softokn3-pkcs11.so distclean: clean .PHONY: all clean distclean ADDED build/tcl/softokn3-pkcs11.c Index: build/tcl/softokn3-pkcs11.c ================================================================== --- build/tcl/softokn3-pkcs11.c +++ build/tcl/softokn3-pkcs11.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include + +#include + +/* + * Create minimal PKCS#11 module interface needed to wrap + */ +#define CK_DEFINE_FUNCTION(type, func) type func + +#define CKR_GENERAL_ERROR 0x00000005 +#define CKR_OK 0x00000000 + +typedef void (*CK_CREATEMUTEX)(); +typedef void (*CK_DESTROYMUTEX)(); +typedef void (*CK_LOCKMUTEX)(); +typedef void (*CK_UNLOCKMUTEX)(); +typedef unsigned long CK_FLAGS; +typedef unsigned long CK_RV; +typedef void * CK_VOID_PTR; + +typedef struct CK_C_INITIALIZE_ARGS { + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + CK_FLAGS flags; + CK_VOID_PTR pReserved; +} CK_C_INITIALIZE_ARGS; + +typedef struct { + unsigned char major; + unsigned char minor; +} CK_VERSION; + +typedef struct { + CK_VERSION version; + CK_RV (*C_Initialize)(CK_VOID_PTR); + CK_RV (*C_Finalize)(CK_VOID_PTR); +} CK_FUNCTION_LIST; + +typedef CK_FUNCTION_LIST* CK_FUNCTION_LIST_PTR; +typedef CK_FUNCTION_LIST** CK_FUNCTION_LIST_PTR_PTR; + +/* + * This is the size of the full PKCS#11 function list structure + * (CK_FUNCTION_LIST). We only actually care about wrapping the + * initialization function, so we have to compute the full size + * + * Size is sizeOf(ourFunctionListStruct) + (numberOfFunctions-2 * functionPointerSize) + */ +#define SIZE_OF_PKCS11_FUNCTION_LIST (sizeof(CK_FUNCTION_LIST) + (67 * sizeof(void *))) + +/* + * Real C_Initialize() function for this module + */ +static CK_RV (*Real_C_Initialize)(CK_VOID_PTR) = NULL; + +static CK_DEFINE_FUNCTION(CK_RV, Proxy_C_Initialize)(CK_VOID_PTR pInitArgs) { + char nssConfig[1024]; + char *nssDBDir = NULL; + CK_C_INITIALIZE_ARGS *InitArgs = NULL; + + InitArgs = pInitArgs; + + if (InitArgs == NULL) { + InitArgs = malloc(sizeof(*InitArgs)); + + InitArgs->CreateMutex = NULL; + InitArgs->DestroyMutex = NULL; + InitArgs->LockMutex = NULL; + InitArgs->UnlockMutex = NULL; + InitArgs->flags = 0; + InitArgs->pReserved = NULL; + } + + if (InitArgs->pReserved == NULL) { + nssDBDir = getenv("SOFTOKN3_NSS_DIR"); + + if (nssDBDir) { + snprintf(nssConfig, sizeof(nssConfig), + "configdir='%s' certPrefix='' keyPrefix='' secmod='secmod.db' flags=readOnly", + nssDBDir + ); + + InitArgs->pReserved = (void *) nssConfig; + } + } + + if (Real_C_Initialize == NULL) { + return(CKR_GENERAL_ERROR); + } + + return(Real_C_Initialize(InitArgs)); +} + +CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) { + CK_RV (*Real_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR); + CK_FUNCTION_LIST_PTR copyFunctionList; + void *handle; + CK_RV retval; + char *module; + + module = getenv("SOFTOKN3_MODULE"); + if (!module) { + module = "/usr/lib64/libsoftokn3.so"; + } + + /* handle = dlmopen(LM_ID_NEWLM, module, RTLD_NOW | RTLD_LOCAL); */ + handle = dlopen(module, RTLD_NOW | RTLD_LOCAL); + if (handle == NULL) { + fprintf(stderr, "Unable to open \"%s\": %s\n", module, dlerror()); + + return(CKR_GENERAL_ERROR); + } + + Real_C_GetFunctionList = dlsym(handle, "C_GetFunctionList"); + + if (Real_C_GetFunctionList == NULL) { + return(CKR_GENERAL_ERROR); + } + + retval = Real_C_GetFunctionList(ppFunctionList); + + if (retval != CKR_OK) { + return(retval); + } + + copyFunctionList = malloc(SIZE_OF_PKCS11_FUNCTION_LIST); + memcpy(copyFunctionList, *ppFunctionList, SIZE_OF_PKCS11_FUNCTION_LIST); + *ppFunctionList = copyFunctionList; + + Real_C_Initialize = (*ppFunctionList)->C_Initialize; + (*ppFunctionList)->C_Initialize = Proxy_C_Initialize; + + return(retval); +}