1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
|
#define _GNU_SOURCE
#include <dlfcn.h>
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#define CK_PTR *
#define CK_DEFINE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
#ifndef NULL_PTR
# define NULL_PTR 0
#endif
#include "./pkcs11/pkcs11.h"
#ifndef CACKEY_LIBRARY_FILE
#define CACKEY_LIBRARY_FILE "libcackey_g.so"
#endif
void abort(void);
void free(void *ptr);
static void *libcackey_wrap_handle = NULL_PTR;
typedef enum {
LIBCACKEY_WRAP_MUTEX_UNINIT = 0,
LIBCACKEY_WRAP_MUTEX_INIT,
LIBCACKEY_WRAP_MUTEX_UNLOCKED,
LIBCACKEY_WRAP_MUTEX_LOCKED,
static void libcackey_wrap_init(void);
} libcackey_wrap_mutexes_states_t;
static libcackey_wrap_mutexes_states_t libcackey_wrap_mutexes[16] = {LIBCACKEY_WRAP_MUTEX_UNINIT};
typedef libcackey_wrap_mutexes_states_t *pthread_mutex_t;
typedef int pthread_mutexattr_t;
static CK_RV libcackey_wrap_createmutex(CK_VOID_PTR_PTR ppMutex) {
int (*create_mutex)(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t *pthread_mutex;
int pthread_retval;
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr) {
libcackey_wrap_mutexes_states_t *mutex_;
int idx;
for (idx = 0; idx < (sizeof(libcackey_wrap_mutexes) / sizeof(libcackey_wrap_mutexes[0])); idx++) {
if (libcackey_wrap_mutexes[idx] == LIBCACKEY_WRAP_MUTEX_UNINIT) {
libcackey_wrap_init();
pthread_mutex = malloc(sizeof(*pthread_mutex));
create_mutex = dlsym(libcackey_wrap_handle, "pthread_mutex_init");
pthread_retval = create_mutex(pthread_mutex, NULL);
if (pthread_retval != 0) {
return(CKR_GENERAL_ERROR);
}
libcackey_wrap_mutexes[idx] = LIBCACKEY_WRAP_MUTEX_INIT;
mutex_ = &libcackey_wrap_mutexes[idx];
break;
}
}
if (!mutex_) {
return(1);
}
*mutex = mutex_;
return(0);
}
int pthread_mutex_destroy(pthread_mutex_t *mutex) {
**mutex = LIBCACKEY_WRAP_MUTEX_UNINIT;
return(0);
}
*ppMutex = pthread_mutex;
int pthread_mutex_lock(pthread_mutex_t *mutex) {
struct timespec sleeptime;
while (**mutex == LIBCACKEY_WRAP_MUTEX_LOCKED) {
sleeptime.tv_sec = 0;
sleeptime.tv_nsec = 1000000;
nanosleep(&sleeptime, NULL);
fprintf(stderr, "mutex %p is locked\n", mutex); fflush(stderr);
/* Do nothing */
}
fprintf(stderr, "locking mutex %p\n", mutex); fflush(stderr);
**mutex = LIBCACKEY_WRAP_MUTEX_LOCKED;
fprintf(stderr, "locked mutex %p\n", mutex); fflush(stderr);
return(CKR_OK);
}
#define libcackey_wrap_genericmutexfunc(funcName, pthreadName) \
static CK_RV funcName(CK_VOID_PTR pMutex) { \
int (*func)(pthread_mutex_t *mutex); \
pthread_mutex_t *pthread_mutex; \
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
fprintf(stderr, "unlocking mutex %p\n", mutex); fflush(stderr);
int pthread_retval; \
libcackey_wrap_init(); \
pthread_mutex = pMutex; \
**mutex = LIBCACKEY_WRAP_MUTEX_UNLOCKED;
func = dlsym(libcackey_wrap_handle, pthreadName); \
pthread_retval = func(pthread_mutex); \
if (pthread_retval != 0) { \
return(CKR_GENERAL_ERROR); \
} \
if (strcmp(pthreadName, "pthread_mutex_destroy") == 0) { \
free(pthread_mutex); \
} \
return(CKR_OK); \
}
fprintf(stderr, "unlocked mutex %p\n", mutex); fflush(stderr);
return(CKR_OK);
}
libcackey_wrap_genericmutexfunc(libcackey_wrap_destroymutex, "pthread_mutex_destroy")
libcackey_wrap_genericmutexfunc(libcackey_wrap_lockmutex, "pthread_mutex_lock")
libcackey_wrap_genericmutexfunc(libcackey_wrap_unlockmutex, "pthread_mutex_unlock")
static void libcackey_wrap_init(void) {
Dl_info libinfo;
int dladdr_ret;
char *library, *libraryDir, *libraryDirLastSlash;
if (libcackey_wrap_handle) {
|
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
+
|
return;
}
*libraryDirLastSlash = '\0';
asprintf(&library, "%s/" CACKEY_LIBRARY_FILE, libraryDir);
libcackey_wrap_handle = dlmopen(LM_ID_NEWLM, library, RTLD_LOCAL | RTLD_NOW);
libcackey_wrap_handle = dlmopen(LM_ID_NEWLM, , RTLD_LOCAL | RTLD_NOW);
if (!libcackey_wrap_handle) {
fprintf(stderr, "Unable to load \"%s\": %s\n", library, dlerror());
abort();
return;
|