TclPKCS11

Check-in [295f01867c]
Login
Overview
Comment:Updated to support Tcl 8.6 file loading (untested)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 295f01867c5a4ccf54a9ba19afded6b4441ccace3df69c75c02d08b328870402
User & Date: rkeene on 2010-10-10 05:25:07
Other Links: manifest | tags
Context
2010-10-10
05:33
Improved Tcl 8.6 module loading support check-in: 87f454af73 user: rkeene tags: trunk
05:25
Updated to support Tcl 8.6 file loading (untested) check-in: 295f01867c user: rkeene tags: trunk
04:45
Added signing and verification to test Made test less verbose check-in: 0a81f17bc9 user: rkeene tags: trunk
Changes

Modified tclpkcs11.c from [eac26b71e7] to [0e48a30252].

1
2
3
4
5




6
7
8
9
10
11
12
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <tcl.h>





/* PKCS#11 Definitions for the local platform */
#define CK_PTR *
#define CK_DECLARE_FUNCTION(rv, func) rv func
#define CK_DECLARE_FUNCTION_POINTER(rv, func) rv (CK_PTR func)
#define CK_CALLBACK_FUNCTION(rv, func) CK_DECLARE_FUNCTION_POINTER(rv, func)
#define CK_NULL_PTR ((void *) 0)





>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <tcl.h>

#if 10 * TCL_MAJOR_VERSION + TCL_MINOR_VERSION >= 86
#  define TCL_INCLUDES_LOADFILE 1
#endif

/* PKCS#11 Definitions for the local platform */
#define CK_PTR *
#define CK_DECLARE_FUNCTION(rv, func) rv func
#define CK_DECLARE_FUNCTION_POINTER(rv, func) rv (CK_PTR func)
#define CK_CALLBACK_FUNCTION(rv, func) CK_DECLARE_FUNCTION_POINTER(rv, func)
#define CK_NULL_PTR ((void *) 0)
373
374
375
376
377
378
379












































380
381
382
383
384
385
386
		if (chk_rv != CKR_OK) {
			return(chk_rv);
		}
	}

	return(CKR_OK);
}













































/*
 * Tcl Commands
 */
static int tclpkcs11_load_module(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
	struct tclpkcs11_interpdata *interpdata;
	struct tclpkcs11_handle *new_handle;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
		if (chk_rv != CKR_OK) {
			return(chk_rv);
		}
	}

	return(CKR_OK);
}

/*
 * Platform Specific Functions 
 */
static void *tclpkcs11_int_load_module(const char *pathname) {
#ifdef TCL_INCLUDES_LOADFILE
	int tcl_rv;
	Tcl_LoadHandle *new_handle;

	tcl_rv = Tcl_LoadFile(NULL, pathname, NULL, 0, NULL, &new_handle);
	if (tcl_rv != TCL_OK) {
		return(NULL);
	}

	return(new_handle);
#else
	/* XXX: TODO: Replace this with Tcl_Load() in 8.6 or otherwise a system-specific loading mechanism */
	return(dlopen(pathname, RTLD_LAZY | RTLD_LOCAL));
#endif
}
static void tclpkcs11_int_unload_module(void *handle) {
#ifdef TCL_INCLUDES_LOADFILE
	Tcl_FSUnloadFile(NULL, handle);
#else
	/* XXX: TODO: Replace this with Tcl_Unload() in 8.6 or otherwise a system-specific unloading mechanism */
	dlclose(handle);
#endif
	return;
}
static void *tclpkcs11_int_lookup_sym(void *handle, const char *sym) {
#ifdef TCL_INCLUDES_LOADFILE
	Tcl_LoadHandle *tcl_handle;
	void *retval;

	tcl_handle = handle;

	retval = Tcl_FindSymbol(NULL, *tcl_handle, sym);o

	return(retval);
#else
	/* XXX: TODO: Replace this with ... ? in 8.6 or otherwise a system-specific symbol lookup mechanism */
	return(dlsym(handle, sym));
#endif
}

/*
 * Tcl Commands
 */
static int tclpkcs11_load_module(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
	struct tclpkcs11_interpdata *interpdata;
	struct tclpkcs11_handle *new_handle;
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
	pathname = Tcl_GetString(objv[1]);
	if (!pathname) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj("invalid pathname", -1));

		return(TCL_ERROR);
	}

	/* XXX: TODO: Replace this with Tcl_Load() in 8.6 or otherwise a system-specific loading mechanism */
	handle = dlopen(pathname, RTLD_LAZY | RTLD_LOCAL);
	if (!handle) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to load", -1));

		return(TCL_ERROR);
	}

	/* XXX: TODO: Replace this with ... ? in 8.6 or otherwise a system-specific symbol lookup mechanism */
	getFuncList = dlsym(handle, "C_GetFunctionList");
	if (!getFuncList) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to locate C_GetFunctionList symbol in PKCS#11 module", -1));

		return(TCL_ERROR);
	}

	chk_rv = getFuncList(&pkcs11_function_list);







<
|






<
|







460
461
462
463
464
465
466

467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
	pathname = Tcl_GetString(objv[1]);
	if (!pathname) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj("invalid pathname", -1));

		return(TCL_ERROR);
	}


	handle = tclpkcs11_int_load_module(pathname);
	if (!handle) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to load", -1));

		return(TCL_ERROR);
	}


	getFuncList = tclpkcs11_int_lookup_sym(handle, "C_GetFunctionList");
	if (!getFuncList) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to locate C_GetFunctionList symbol in PKCS#11 module", -1));

		return(TCL_ERROR);
	}

	chk_rv = getFuncList(&pkcs11_function_list);
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
		return(TCL_ERROR);
	}

	/* Delete our hash entry */
	Tcl_DeleteHashEntry(tcl_handle_entry);

	/* Attempt to unload the module */
	dlclose(handle->base);

	/* Free our allocated handle */
	ckfree((char *) handle);

	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));

	return(TCL_OK);







|







608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
		return(TCL_ERROR);
	}

	/* Delete our hash entry */
	Tcl_DeleteHashEntry(tcl_handle_entry);

	/* Attempt to unload the module */
	tclpkcs11_int_unload_module(handle->base);

	/* Free our allocated handle */
	ckfree((char *) handle);

	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));

	return(TCL_OK);