pkcs11_luna 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }