pkcs11_luna 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/ext/pk11l.c ADDED
@@ -0,0 +1,352 @@
1
+ #include <ruby.h>
2
+
3
+
4
+ #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
5
+ #define _WINDOWS
6
+ #define OS_WIN32
7
+ #define compile_for_windows
8
+ #else
9
+ #define OS_LINUX
10
+ #endif
11
+
12
+
13
+ #if defined(compile_for_windows)
14
+ #include <winbase.h> /* for LoadLibrary() */
15
+ #else
16
+ #include <dlfcn.h>
17
+ #endif
18
+
19
+
20
+ ///////////////////////////////////////
21
+
22
+ static VALUE mPKCS11;
23
+ static VALUE cPKCS11;
24
+ static VALUE mLuna;
25
+ static VALUE eLunaError;
26
+ static VALUE cLunaCStruct;
27
+ static VALUE cPkcs11CStruct;
28
+
29
+ static VALUE cCK_C_INITIALIZE_ARGS;
30
+ static VALUE aCK_C_INITIALIZE_ARGS_members;
31
+ static VALUE cCK_INFO;
32
+ static VALUE aCK_INFO_members;
33
+ static VALUE cCK_TOKEN_INFO;
34
+ static VALUE aCK_TOKEN_INFO_members;
35
+ static VALUE cCK_SLOT_INFO;
36
+ static VALUE aCK_SLOT_INFO_members;
37
+ static VALUE cCK_MECHANISM_INFO;
38
+ static VALUE aCK_MECHANISM_INFO_members;
39
+ static VALUE cCK_SESSION_INFO;
40
+ static VALUE aCK_SESSION_INFO_members;
41
+ static VALUE cCK_MECHANISM;
42
+
43
+ static VALUE vOBJECT_CLASSES;
44
+ static VALUE vATTRIBUTES;
45
+ static VALUE vMECHANISMS;
46
+ static VALUE vRETURN_VALUES;
47
+
48
+ #define MODULE_FOR_STRUCTS mLuna
49
+ #define MODULE_FOR_CONSTS mLuna
50
+ #define BASECLASS_FOR_ERRORS eLunaError
51
+ #define BASECLASS_FOR_STRUCTS cLunaCStruct
52
+
53
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
54
+ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
55
+ rb_unblock_function_t *ubf, void *data2);
56
+ #endif
57
+
58
+ #define PKCS11_DEFINE_METHOD(name, args) \
59
+ rb_define_method(cPKCS11, #name, pkcs11_luna_##name, args);
60
+
61
+ #define GetFunction(obj, name, sval) \
62
+ { \
63
+ pkcs11_luna_ctx *ctx; \
64
+ Data_Get_Struct(obj, pkcs11_luna_ctx, ctx); \
65
+ if (!ctx->sfnt_functions) rb_raise(eLunaError, "no function list"); \
66
+ sval = (CK_##name)ctx->sfnt_functions->name; \
67
+ if (!sval) rb_raise(eLunaError, #name " is not supported."); \
68
+ }
69
+
70
+ #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
71
+ #define CallFunction(name, func, rv, ...) \
72
+ { \
73
+ struct tbr_##name##_params params = { \
74
+ func, {__VA_ARGS__}, CKR_FUNCTION_FAILED \
75
+ }; \
76
+ rb_thread_call_without_gvl(tbf_##name, &params, RUBY_UBF_PROCESS, NULL); \
77
+ rv = params.retval; \
78
+ }
79
+ #else
80
+ #define CallFunction(name, func, rv, ...) \
81
+ rv = func(__VA_ARGS__)
82
+ #endif
83
+
84
+ #include "cryptoki_v2.h"
85
+
86
+ #include "pk11_struct_macros.h"
87
+ #include "pk11_const_macros.h"
88
+ #include "pk11_version.h"
89
+
90
+ #include "pk11l_struct_impl.inc"
91
+
92
+ typedef struct {
93
+ void *module;
94
+ CK_FUNCTION_LIST_PTR functions;
95
+ CK_SFNT_CA_FUNCTION_LIST_PTR sfnt_functions;
96
+ } pkcs11_luna_ctx;
97
+
98
+ static void
99
+ pkcs11_luna_raise(VALUE self, CK_RV rv)
100
+ {
101
+ rb_funcall(self, rb_intern("vendor_raise_on_return_value"), 1, ULONG2NUM(rv));
102
+ rb_raise(eLunaError, "method vendor_raise_on_return_value should never return");
103
+ }
104
+
105
+ #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
106
+
107
+ struct tbr_CA_GetFunctionList_params {
108
+ CK_CA_GetFunctionList func;
109
+ struct { CK_SFNT_CA_FUNCTION_LIST_PTR_PTR ppSfntFunctionList; } params;
110
+ CK_RV retval;
111
+ };
112
+
113
+ void * tbf_CA_GetFunctionList( void *data ){
114
+ struct tbr_CA_GetFunctionList_params *p = (struct tbr_CA_GetFunctionList_params*)data;
115
+ p->retval = p->func( p->params.ppSfntFunctionList );
116
+ return NULL;
117
+ }
118
+
119
+ /*struct tbr_CA_SetApplicationID_params {
120
+ CK_CA_SetApplicationID func;
121
+ struct { CK_ULONG major; CK_ULONG minor; } params;l
122
+ CK_RV retval;
123
+ };
124
+
125
+ void * tbf_CA_SetApplicationID( void *data ){
126
+ struct tbr_CA_SetApplicationID_params *p = (struct tbr_CA_SetApplicationID_params*)data;
127
+ p->retval = p->func( p->params.major, p->params.minor );
128
+ return NULL;
129
+ }
130
+
131
+ struct tbr_CA_OpenApplicationID_params {
132
+ CK_CA_OpenApplicationID func;
133
+ struct { CK_SLOT_ID slot_id; CK_ULONG major; CK_ULONG minor; } params;
134
+ CK_RV retval;
135
+ };
136
+
137
+ void * tbf_CA_OpenApplicationID( void *data ){
138
+ struct tbr_CA_OpenApplicationID_params *p = (struct tbr_CA_OpenApplicationID_params*)data;
139
+ p->retval = p->func( p->params.slot_id, p->params.major, p->params.minor );
140
+ return NULL;
141
+ }
142
+
143
+ struct tbr_CA_CloseApplicationID_params {
144
+ CK_CA_CloseApplicationID func;
145
+ struct { CK_SLOT_ID slot_id; CK_ULONG major; CK_ULONG minor; } params;
146
+ CK_RV retval;
147
+ };
148
+
149
+ void * tbf_CA_CloseApplicationID( void *data ){
150
+ struct tbr_CA_CloseApplicationID_params *p = (struct tbr_CA_CloseApplicationID_params*)data;
151
+ p->retval = p->func( p->params.slot_id, p->params.major, p->params.minor);
152
+ return NULL;
153
+ }
154
+
155
+ struct tbr_CA_LogExternal_params {
156
+ CK_CA_LogExternal func;
157
+ struct { CK_SLOT_ID slot_id; CK_SESSION_HANDLE hSession; CK_CHAR_PTR pString; CK_ULONG ulLen;} params;
158
+ CK_RV retval;
159
+ };
160
+
161
+ void * tbf_CA_LogExternal( void *data ){
162
+ struct tbr_CA_LogExternal_params *p = (struct tbr_CA_LogExternal_params*)data;
163
+ p->retval = p->func( p->params.slot_id, p->params.hSession, p->params.pString, p->params.ulLen);
164
+ return NULL;
165
+ }*/
166
+
167
+ #endif
168
+
169
+
170
+
171
+ static void
172
+ pkcs11_luna_ctx_free(pkcs11_luna_ctx *ctx)
173
+ {
174
+ free(ctx);
175
+ }
176
+
177
+ //NOTE: Code commented out as it was decided to only support standard pkcs11 initially.l
178
+
179
+ /*static VALUE
180
+ pkcs11_luna_CA_SetApplicationID(VALUE self, VALUE major, VALUE minor)
181
+ {
182
+ CK_CA_SetApplicationID func;
183
+ CK_RV rv;
184
+
185
+ GetFunction(self, CA_SetApplicationID, func);
186
+ CallFunction(CA_SetApplicationID, func, rv, NUM2ULONG(major), NUM2ULONG(minor));
187
+ if(rv != CKR_OK)
188
+ pkcs11_luna_raise(self,rv);
189
+ return self;
190
+ }
191
+
192
+ static VALUE
193
+ pkcs11_luna_CA_OpenApplicationID(VALUE self, VALUE slot_id, VALUE major, VALUE minor)
194
+ {
195
+ CK_CA_OpenApplicationID func;
196
+ CK_RV rv;
197
+
198
+ GetFunction(self, CA_OpenApplicationID, func);
199
+ CallFunction(CA_OpenApplicationID, func, rv, NUM2ULONG(slot_id), NUM2ULONG(major), NUM2ULONG(minor));
200
+ if(rv != CKR_OK)
201
+ pkcs11_luna_raise(self,rv);
202
+ return self;
203
+ }
204
+
205
+ static VALUE
206
+ pkcs11_luna_CA_CloseApplicationID(VALUE self, VALUE slot_id, VALUE major, VALUE minor)
207
+ {
208
+ CK_CA_CloseApplicationID func;
209
+ CK_RV rv;
210
+
211
+ GetFunction(self, CA_CloseApplicationID, func);
212
+ CallFunction(CA_CloseApplicationID, func, rv, NUM2ULONG(slot_id), NUM2ULONG(major), NUM2ULONG(minor));
213
+ if(rv != CKR_OK)
214
+ pkcs11_luna_raise(self,rv);
215
+ return self;
216
+ }*/
217
+
218
+ /*static VALUE
219
+ pkcs11_luna_CA_LogExternal(VALUE self, VALUE slot_id, VALUE session, VALUE message) {
220
+ CK_CA_LogExternal func;
221
+ CK_RV rv;
222
+
223
+ GetFunction(self, CA_LogExternal, func);
224
+ CallFunction(CA_LogExternal, func, rv, NUM2HANDLE(slot_id), NUM2HANDLE(session),
225
+ (CK_CHAR_PTR)RSTRING_PTR(message), RSTRING_LEN(message));
226
+ if(rv != CKR_OK) pkcs11_luna_raise(self,rv);
227
+
228
+ return self;
229
+ }*/
230
+
231
+
232
+ /* rb_define_method(cPKCS11, "CA_GetFunctionList", pkcs11_CA_GetFunctionList, 0); */
233
+ /*
234
+ * Obtains a pointer to the Cryptoki library's list of function pointers. The pointer
235
+ * is stored in the {PKCS11::Library} object and used to call any Cryptoki functions.
236
+ *
237
+ * @see PKCS11::Library#initialize
238
+ */
239
+ static VALUE
240
+ pkcs11_luna_CA_GetFunctionList(VALUE self)
241
+ {
242
+ pkcs11_luna_ctx *ctx;
243
+ CK_RV rv;
244
+ CK_CA_GetFunctionList func;
245
+
246
+ Data_Get_Struct(self, pkcs11_luna_ctx, ctx);
247
+ #ifdef compile_for_windows
248
+ func = (CK_CA_GetFunctionList)GetProcAddress(ctx->module, "CA_GetFunctionList");
249
+ if(!func){
250
+ char error_text[999] = "GetProcAddress() error";
251
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
252
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
253
+ (LPTSTR)&error_text, sizeof(error_text), NULL);
254
+ rb_raise(eLunaError, "%s", error_text);
255
+ }
256
+ #else
257
+ func = (CK_CA_GetFunctionList)dlsym(ctx->module, "CA_GetFunctionList");
258
+ if(!func) rb_raise(eLunaError, "%sHERE", dlerror());
259
+ #endif
260
+ CallFunction(CA_GetFunctionList, func, rv, &(ctx->sfnt_functions));
261
+ if (rv != CKR_OK)
262
+ pkcs11_luna_raise(self, rv);
263
+
264
+ return self;
265
+ }
266
+
267
+ static VALUE
268
+ pkcs11_luna_s_alloc(VALUE self)
269
+ {
270
+ VALUE obj;
271
+ pkcs11_luna_ctx *ctx;
272
+ obj = Data_Make_Struct(self, pkcs11_luna_ctx, 0, pkcs11_luna_ctx_free, ctx);
273
+ return obj;
274
+ }
275
+
276
+ static VALUE
277
+ pkcs11_luna_initialize(int argc, VALUE *argv, VALUE self)
278
+ {
279
+ VALUE path, init_args;
280
+
281
+ rb_scan_args(argc, argv, "02", &path, &init_args);
282
+ if( !NIL_P(path) ){
283
+ rb_funcall(self, rb_intern("load_library"), 1, path);
284
+ rb_funcall(self, rb_intern("C_GetFunctionList"), 0);
285
+ rb_funcall(self, rb_intern("CA_GetFunctionList"), 0);
286
+ rb_funcall2(self, rb_intern("C_Initialize"), 1, &init_args);
287
+ }
288
+
289
+ return self;
290
+ }
291
+
292
+ void
293
+ Init_pkcs11_luna_ext()
294
+ {
295
+ VALUE eError;
296
+ VALUE cLibrary;
297
+
298
+ mPKCS11 = rb_const_get(rb_cObject, rb_intern("PKCS11"));
299
+
300
+ /* Document-module: PKCS11::Luna
301
+ *
302
+ * Module to provide functionality for SafeNet's Luna HSMs */
303
+ mLuna = rb_define_module_under(mPKCS11, "Luna");
304
+
305
+ /* Document-class: PKCS11::Luna::Library
306
+ *
307
+ * Derived class for Luna Library */
308
+ cLibrary = rb_const_get(mPKCS11, rb_intern("Library"));
309
+
310
+ cPKCS11 = rb_define_class_under(mLuna, "Library", cLibrary);
311
+
312
+ rb_define_alloc_func(cPKCS11, pkcs11_luna_s_alloc);
313
+ rb_define_method(cPKCS11, "initialize", pkcs11_luna_initialize, -1);
314
+
315
+ PKCS11_DEFINE_METHOD(CA_GetFunctionList, 0);
316
+ //PKCS11_DEFINE_METHOD(CA_LogExternal, 3);
317
+ //PKCS11_DEFINE_METHOD(CA_SetApplicationID, 2);
318
+ //PKCS11_DEFINE_METHOD(CA_OpenApplicationID, 3);
319
+ //PKCS11_DEFINE_METHOD(CA_CloseApplicationID, 3);
320
+
321
+
322
+ /* Library version */
323
+ rb_define_const( mLuna, "VERSION", rb_str_new2(VERSION) );
324
+
325
+ eError = rb_const_get(mPKCS11, rb_intern("Error"));
326
+ /* Document-class: PKCS11::Luna::Error
327
+ *
328
+ * Base class for all Luna specific exceptions (CKR_*) */
329
+ eLunaError = rb_define_class_under(mLuna, "Error", eError);
330
+
331
+ cPkcs11CStruct = rb_const_get(mPKCS11, rb_intern("CStruct")); \
332
+ cLunaCStruct = rb_define_class_under(mLuna, "CStruct", cPkcs11CStruct);
333
+
334
+ #include "pk11l_struct_def.inc"
335
+
336
+ vOBJECT_CLASSES = rb_hash_new();
337
+ vATTRIBUTES = rb_hash_new();
338
+ vMECHANISMS = rb_hash_new();
339
+ vRETURN_VALUES = rb_hash_new();
340
+ rb_define_const(mLuna, "OBJECT_CLASSES", vOBJECT_CLASSES);
341
+ rb_define_const(mLuna, "ATTRIBUTES", vATTRIBUTES);
342
+ rb_define_const(mLuna, "MECHANISMS", vMECHANISMS);
343
+ rb_define_const(mLuna, "RETURN_VALUES", vRETURN_VALUES);
344
+
345
+ #include "pk11l_const_def.inc"
346
+
347
+ rb_obj_freeze(vOBJECT_CLASSES);
348
+ rb_obj_freeze(vATTRIBUTES);
349
+ rb_obj_freeze(vMECHANISMS);
350
+ rb_obj_freeze(vRETURN_VALUES);
351
+
352
+ }