23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
|
#if 10 * TCL_MAJOR_VERSION + TCL_MINOR_VERSION >= 86
# define TCL_INCLUDES_LOADFILE 1
#endif
/* PKCS#11 Definitions for the local platform */
#ifndef _WIN32
#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) rv (CK_PTR func)
#define CK_NULL_PTR ((void *) 0)
# 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) rv (CK_PTR func)
# define CK_NULL_PTR ((void *) 0)
#else
#define CK_PTR *
#define CK_DECLARE_FUNCTION(rv, func) rv __declspec(dllimport) func
#define CK_DECLARE_FUNCTION_POINTER(rv, func) rv __declspec(dllimport) (CK_PTR func)
#define CK_CALLBACK_FUNCTION(rv, func) rv (CK_PTR func)
#define CK_NULL_PTR ((void *) 0)
# define CK_PTR *
# define CK_DECLARE_FUNCTION(rv, func) rv __declspec(dllimport) func
# define CK_DECLARE_FUNCTION_POINTER(rv, func) rv __declspec(dllimport) (CK_PTR func)
# define CK_CALLBACK_FUNCTION(rv, func) rv (CK_PTR func)
# define CK_NULL_PTR ((void *) 0)
# pragma pack(push, cryptoki, 1)
#endif
#include "pkcs11.h"
#ifdef _WIN32
# pragma pack(pop, cryptoki)
#endif
struct tclpkcs11_interpdata {
/* Handle Hash Table */
Tcl_HashTable handles;
unsigned long handles_idx;
};
|
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
|
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
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);
}
#ifndef _WIN32
chk_rv = getFuncList(&pkcs11_function_list);
if (chk_rv != CKR_OK) {
Tcl_SetObjResult(interp, tclpkcs11_pkcs11_error(chk_rv));
return(TCL_ERROR);
}
if (!pkcs11_function_list) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned invalid data", -1));
return(TCL_ERROR);
}
if (!pkcs11_function_list->C_Initialize) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data", -1));
return(TCL_ERROR);
}
#else
/*
* Retreiving the functions from C_GetFunctionList does not seem to be
*reliable on Win32
*/
pkcs11_function_list = (CK_FUNCTION_LIST_PTR) ckalloc(sizeof(*pkcs11_function_list));
pkcs11_function_list->C_CloseSession = tclpkcs11_int_lookup_sym(handle, "C_CloseSession");
if (pkcs11_function_list->C_CloseSession == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_CloseSession)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_Decrypt = tclpkcs11_int_lookup_sym(handle, "C_Decrypt");
if (pkcs11_function_list->C_Decrypt == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_Decrypt)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_DecryptFinal = tclpkcs11_int_lookup_sym(handle, "C_DecryptFinal");
if (pkcs11_function_list->C_DecryptFinal == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_DecryptFinal)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_DecryptInit = tclpkcs11_int_lookup_sym(handle, "C_DecryptInit");
if (pkcs11_function_list->C_DecryptInit == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_DecryptInit)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_Encrypt = tclpkcs11_int_lookup_sym(handle, "C_Encrypt");
if (pkcs11_function_list->C_Encrypt == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_Encrypt)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_EncryptInit = tclpkcs11_int_lookup_sym(handle, "C_EncryptInit");
if (pkcs11_function_list->C_EncryptInit == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_EncryptInit)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_Finalize = tclpkcs11_int_lookup_sym(handle, "C_Finalize");
if (pkcs11_function_list->C_Finalize == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_Finalize)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_FindObjects = tclpkcs11_int_lookup_sym(handle, "C_FindObjects");
if (pkcs11_function_list->C_FindObjects == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_FindObjects)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_FindObjectsFinal = tclpkcs11_int_lookup_sym(handle, "C_FindObjectsFinal");
if (pkcs11_function_list->C_FindObjectsFinal == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_FindObjectsFinal)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_FindObjectsInit = tclpkcs11_int_lookup_sym(handle, "C_FindObjectsInit");
if (pkcs11_function_list->C_FindObjectsInit == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_FindObjectsInit)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_GetAttributeValue = tclpkcs11_int_lookup_sym(handle, "C_GetAttributeValue");
if (pkcs11_function_list->C_GetAttributeValue == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_GetAttributeValue)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_GetSlotInfo = tclpkcs11_int_lookup_sym(handle, "C_GetSlotInfo");
if (pkcs11_function_list->C_GetSlotInfo == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_GetSlotInfo)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_GetSlotList = tclpkcs11_int_lookup_sym(handle, "C_GetSlotList");
if (pkcs11_function_list->C_GetSlotList == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_GetSlotList)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_GetTokenInfo = tclpkcs11_int_lookup_sym(handle, "C_GetTokenInfo");
if (pkcs11_function_list->C_GetTokenInfo == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_GetTokenInfo)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_Initialize = tclpkcs11_int_lookup_sym(handle, "C_Initialize");
if (pkcs11_function_list->C_Initialize == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_Initialize)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_Login = tclpkcs11_int_lookup_sym(handle, "C_Login");
if (pkcs11_function_list->C_Login == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_Login)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_Logout = tclpkcs11_int_lookup_sym(handle, "C_Logout");
if (pkcs11_function_list->C_Logout == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_Logout)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_OpenSession = tclpkcs11_int_lookup_sym(handle, "C_OpenSession");
if (pkcs11_function_list->C_OpenSession == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_OpenSession)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_Sign = tclpkcs11_int_lookup_sym(handle, "C_Sign");
if (pkcs11_function_list->C_Sign == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_Sign)", -1));
return(TCL_ERROR);
}
pkcs11_function_list->C_SignInit = tclpkcs11_int_lookup_sym(handle, "C_SignInit");
if (pkcs11_function_list->C_SignInit == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data (missing C_SignInit)", -1));
return(TCL_ERROR);
}
#endif
initargs.CreateMutex = tclpkcs11_create_mutex;
initargs.DestroyMutex = tclpkcs11_destroy_mutex;
initargs.LockMutex = tclpkcs11_lock_mutex;
initargs.UnlockMutex = tclpkcs11_unlock_mutex;
initargs.flags = 0;
initargs.LibraryFlags = NULL;
initargs.pReserved = NULL;
|
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
|
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
MODULE_SCOPE int tclpkcs11_encrypt(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
return(tclpkcs11_perform_pki(1, cd, interp, objc, objv));
}
MODULE_SCOPE int tclpkcs11_decrypt(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
return(tclpkcs11_perform_pki(0, cd, interp, objc, objv));
}
MODULE_SCOPE void tclpkcs11_unloadall(ClientData cd) {
struct tclpkcs11_interpdata *interpdata;
struct tclpkcs11_handle *handle;
Tcl_HashEntry *tcl_handle_entry;
Tcl_HashSearch search;
if (!cd) {
return;
}
interpdata = (struct tclpkcs11_interpdata *) cd;
for (
tcl_handle_entry = Tcl_FirstHashEntry(&interpdata->handles, &search);
tcl_handle_entry;
tcl_handle_entry = Tcl_NextHashEntry(&search)
) {
handle = (struct tclpkcs11_handle *) Tcl_GetHashValue(tcl_handle_entry);
if (handle->pkcs11 && handle->pkcs11->C_Finalize) {
handle->pkcs11->C_Finalize(NULL);
}
tclpkcs11_int_unload_module(handle->base);
ckfree((char *) handle);
}
return;
}
/*
* Tcl Loadable Module Initialization
*/
int Tclpkcs11_Init(Tcl_Interp *interp) {
struct tclpkcs11_interpdata *interpdata;
Tcl_Command tclCreatComm_ret;
|
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
|
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
|
+
+
+
|
return(TCL_ERROR);
}
tclCreatComm_ret = Tcl_CreateObjCommand(interp, "pki::pkcs11::decrypt", tclpkcs11_decrypt, interpdata, NULL);
if (!tclCreatComm_ret) {
return(TCL_ERROR);
}
/* Create an exit handler to unload and close all PKCS#11 modules */
Tcl_CreateExitHandler(tclpkcs11_unloadall, interpdata);
/* Register PKI handlers */
Tcl_ObjSetVar2(interp,
Tcl_NewStringObj("pki::handlers", -1),
Tcl_NewStringObj("pkcs11", -1),
Tcl_NewStringObj("::pki::pkcs11::encrypt ::pki::pkcs11::decrypt", -1),
TCL_GLOBAL_ONLY
|