pkcs11 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/ext/pk11.c ADDED
@@ -0,0 +1,1737 @@
1
+ #include "pk11.h"
2
+
3
+ #if defined(compile_for_windows)
4
+ #include <winbase.h> /* for LoadLibrary() */
5
+ #else
6
+ #include <dlfcn.h>
7
+ #endif
8
+
9
+ static const char *VERSION = "0.1.0";
10
+
11
+ static ID sNEW;
12
+ static VALUE mPKCS11;
13
+ static VALUE cPKCS11;
14
+ static VALUE ePKCS11Error;
15
+
16
+ static VALUE cCK_ATTRIBUTE;
17
+ static VALUE cCK_C_INITIALIZE_ARGS;
18
+ static VALUE cCK_INFO;
19
+ static VALUE cCK_TOKEN_INFO;
20
+ static VALUE cCK_SLOT_INFO;
21
+ static VALUE cCK_MECHANISM_INFO;
22
+ static VALUE cCK_SESSION_INFO;
23
+ static VALUE cCK_MECHANISM;
24
+
25
+ #define HANDLE2NUM(n) ULONG2NUM(n)
26
+ #define NUM2HANDLE(n) PKNUM2ULONG(n)
27
+ #define PKNUM2ULONG(n) pkcs11_num2ulong(n)
28
+ #define pkcs11_new_struct(klass) rb_funcall(klass, sNEW, 0)
29
+
30
+ VALUE pkcs11_return_value_to_name(CK_RV);
31
+
32
+ static VALUE
33
+ pkcs11_num2ulong(VALUE val)
34
+ {
35
+ if (TYPE(val) == T_BIGNUM || TYPE(val) == T_FIXNUM) {
36
+ return NUM2ULONG(val);
37
+ }
38
+ return NUM2ULONG(rb_to_int(val));
39
+ }
40
+
41
+ static void
42
+ pkcs11_raise(CK_RV rv)
43
+ {
44
+ VALUE message;
45
+ message = pkcs11_return_value_to_name(rv);
46
+ rb_raise(ePKCS11Error, "%s", RSTRING_PTR(message));
47
+ }
48
+
49
+ ///////////////////////////////////////
50
+
51
+ typedef struct {
52
+ void *module;
53
+ CK_FUNCTION_LIST_PTR functions;
54
+ } pkcs11_ctx;
55
+
56
+ #define GetFunction(obj, name, sval) \
57
+ { \
58
+ pkcs11_ctx *ctx; \
59
+ Data_Get_Struct(self, pkcs11_ctx, ctx); \
60
+ if (!ctx->functions) rb_raise(ePKCS11Error, "library already closed"); \
61
+ sval = (CK_##name)ctx->functions->name; \
62
+ if (!sval) rb_raise(ePKCS11Error, #name " is not supported."); \
63
+ } while(0)
64
+
65
+ static void
66
+ pkcs11_ctx_unload_library(pkcs11_ctx *ctx)
67
+ {
68
+ if(ctx->functions) ctx->functions->C_Finalize(NULL_PTR);
69
+ #ifdef compile_for_windows
70
+ if(ctx->module) FreeLibrary(ctx->module);
71
+ #else
72
+ if(ctx->module) dlclose(ctx->module);
73
+ #endif
74
+ ctx->module = NULL;
75
+ ctx->functions = NULL;
76
+ }
77
+
78
+ static void
79
+ pkcs11_ctx_free(pkcs11_ctx *ctx)
80
+ {
81
+ pkcs11_ctx_unload_library(ctx);
82
+ free(ctx);
83
+ }
84
+
85
+ static VALUE
86
+ pkcs11_C_Finalize(VALUE self)
87
+ {
88
+ pkcs11_ctx *ctx;
89
+
90
+ Data_Get_Struct(self, pkcs11_ctx, ctx);
91
+ pkcs11_ctx_unload_library(ctx);
92
+ return Qnil;
93
+ }
94
+
95
+ static VALUE
96
+ pkcs11_s_alloc(VALUE self)
97
+ {
98
+ VALUE obj;
99
+ pkcs11_ctx *ctx;
100
+ obj = Data_Make_Struct(self, pkcs11_ctx, 0, pkcs11_ctx_free, ctx);
101
+ return obj;
102
+ }
103
+
104
+ static VALUE
105
+ pkcs11_library_new(int argc, VALUE *argv, VALUE self)
106
+ {
107
+ return rb_funcall2(cPKCS11, sNEW, argc, argv);
108
+ }
109
+
110
+ static VALUE
111
+ pkcs11_initialize(int argc, VALUE *argv, VALUE self)
112
+ {
113
+ VALUE path, init_args;
114
+ pkcs11_ctx *ctx;
115
+ const char *so_path;
116
+ CK_C_GetFunctionList func;
117
+ CK_C_INITIALIZE_ARGS *args;
118
+ CK_RV rv;
119
+
120
+ rb_scan_args(argc, argv, "11", &path, &init_args);
121
+ so_path = StringValuePtr(path);
122
+ if (NIL_P(init_args)) args = NULL_PTR;
123
+ else {
124
+ if (!rb_obj_is_kind_of(init_args, cCK_C_INITIALIZE_ARGS))
125
+ rb_raise(rb_eArgError, "2nd arg must be a PKCS11::CK_C_INITIALIZE_ARGS");
126
+ args = DATA_PTR(init_args);
127
+ }
128
+ args = NIL_P(init_args) ? NULL_PTR : DATA_PTR(init_args);
129
+
130
+ Data_Get_Struct(self, pkcs11_ctx, ctx);
131
+ #ifdef compile_for_windows
132
+ if((ctx->module = LoadLibrary(so_path)) == NULL) {
133
+ char error_text[999] = "LoadLibrary() error";
134
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
135
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
136
+ (LPTSTR)&error_text, sizeof(error_text), NULL);
137
+ rb_raise(ePKCS11Error, error_text);
138
+ }
139
+ func = (CK_C_GetFunctionList)GetProcAddress(ctx->module, "C_GetFunctionList");
140
+ if(!func){
141
+ char error_text[999] = "GetProcAddress() error";
142
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
143
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
144
+ (LPTSTR)&error_text, sizeof(error_text), NULL);
145
+ rb_raise(ePKCS11Error, error_text);
146
+ }
147
+ #else
148
+ if((ctx->module = dlopen(so_path, RTLD_NOW)) == NULL) {
149
+ rb_raise(ePKCS11Error, "%s", dlerror());
150
+ }
151
+ func = (CK_C_GetFunctionList)dlsym(ctx->module, "C_GetFunctionList");
152
+ if(!func) rb_raise(ePKCS11Error, "%s", dlerror());
153
+ #endif
154
+ if((rv = func(&(ctx->functions))) != CKR_OK) pkcs11_raise(rv);
155
+ if ((rv = ctx->functions->C_Initialize(args)) != CKR_OK) pkcs11_raise(rv);
156
+
157
+ return self;
158
+ }
159
+
160
+ static VALUE
161
+ pkcs11_C_GetInfo(VALUE self)
162
+ {
163
+ CK_C_GetInfo func;
164
+ CK_RV rv;
165
+ VALUE info;
166
+
167
+ GetFunction(self, C_GetInfo, func);
168
+ info = pkcs11_new_struct(cCK_INFO);
169
+ rv = func((CK_INFO_PTR)DATA_PTR(info));
170
+ if (rv != CKR_OK) pkcs11_raise(rv);
171
+
172
+ return info;
173
+ }
174
+
175
+ static VALUE
176
+ pkcs11_C_GetSlotList(VALUE self, VALUE presented)
177
+ {
178
+ CK_ULONG ulSlotCount;
179
+ CK_SLOT_ID_PTR pSlotList;
180
+ CK_RV rv;
181
+ CK_C_GetSlotList func;
182
+ int i;
183
+ VALUE ary = rb_ary_new();
184
+
185
+ GetFunction(self, C_GetSlotList, func);
186
+ rv = func(CK_FALSE, NULL_PTR, &ulSlotCount);
187
+ if (rv != CKR_OK) pkcs11_raise(rv);
188
+ pSlotList = (CK_SLOT_ID_PTR)malloc(ulSlotCount*sizeof(CK_SLOT_ID));
189
+ rv = func(RTEST(presented) ? CK_TRUE : CK_FALSE, pSlotList, &ulSlotCount);
190
+ if (rv != CKR_OK) {
191
+ free(pSlotList);
192
+ pkcs11_raise(rv);
193
+ }
194
+ for (i = 0; i < ulSlotCount; i++)
195
+ rb_ary_push(ary, HANDLE2NUM(pSlotList[i]));
196
+ free(pSlotList);
197
+
198
+ return ary;
199
+ }
200
+
201
+ static VALUE
202
+ pkcs11_C_GetSlotInfo(VALUE self, VALUE slot_id)
203
+ {
204
+ CK_RV rv;
205
+ CK_C_GetSlotInfo func;
206
+ VALUE info;
207
+
208
+ GetFunction(self, C_GetSlotInfo, func);
209
+ info = pkcs11_new_struct(cCK_SLOT_INFO);
210
+ rv = func(NUM2HANDLE(slot_id), DATA_PTR(info));
211
+ if (rv != CKR_OK) pkcs11_raise(rv);
212
+
213
+ return info;
214
+ }
215
+
216
+ static VALUE
217
+ pkcs11_C_GetTokenInfo(VALUE self, VALUE slot_id)
218
+ {
219
+ CK_RV rv;
220
+ CK_C_GetTokenInfo func;
221
+ VALUE info;
222
+
223
+ GetFunction(self, C_GetTokenInfo, func);
224
+ info = pkcs11_new_struct(cCK_TOKEN_INFO);
225
+ rv = func(NUM2HANDLE(slot_id), DATA_PTR(info));
226
+ if (rv != CKR_OK) pkcs11_raise(rv);
227
+
228
+ return info;
229
+ }
230
+
231
+ static VALUE
232
+ pkcs11_C_GetMechanismList(VALUE self, VALUE slot_id)
233
+ {
234
+ CK_RV rv;
235
+ CK_C_GetMechanismList func;
236
+ CK_MECHANISM_TYPE_PTR types;
237
+ CK_ULONG count;
238
+ VALUE ary;
239
+ int i;
240
+
241
+ ary = rb_ary_new();
242
+ GetFunction(self, C_GetMechanismList, func);
243
+ rv = func(NUM2HANDLE(slot_id), NULL_PTR, &count);
244
+ if (rv != CKR_OK) pkcs11_raise(rv);
245
+ if (count == 0) return ary;
246
+
247
+ types = (CK_MECHANISM_TYPE_PTR)malloc(sizeof(CK_MECHANISM_TYPE)*count);
248
+ if (!types) rb_sys_fail(0);
249
+ rv = func(NUM2HANDLE(slot_id), types, &count);
250
+ if (rv != CKR_OK){
251
+ free(types);
252
+ pkcs11_raise(rv);
253
+ }
254
+ for (i = 0; i < count; i++)
255
+ rb_ary_push(ary, HANDLE2NUM(*(types+i)));
256
+ free(types);
257
+
258
+ return ary;
259
+ }
260
+
261
+ static VALUE
262
+ pkcs11_C_GetMechanismInfo(VALUE self, VALUE slot_id, VALUE type)
263
+ {
264
+ CK_RV rv;
265
+ CK_C_GetMechanismInfo func;
266
+ VALUE info;
267
+
268
+ info = pkcs11_new_struct(cCK_MECHANISM_INFO);
269
+ GetFunction(self, C_GetMechanismInfo, func);
270
+ rv = func(NUM2HANDLE(slot_id), NUM2HANDLE(type), DATA_PTR(info));
271
+ if (rv != CKR_OK) pkcs11_raise(rv);
272
+
273
+ return info;
274
+ }
275
+
276
+ static VALUE
277
+ pkcs11_C_InitToken(VALUE self, VALUE slot_id, VALUE pin, VALUE label)
278
+ {
279
+ CK_RV rv;
280
+ CK_C_InitToken func;
281
+
282
+ StringValue(pin);
283
+ StringValue(label);
284
+ GetFunction(self, C_InitToken, func);
285
+ rv = func(NUM2HANDLE(slot_id),
286
+ (CK_UTF8CHAR_PTR)RSTRING_PTR(pin), RSTRING_LEN(pin),
287
+ (CK_UTF8CHAR_PTR)RSTRING_PTR(label));
288
+ if (rv != CKR_OK) pkcs11_raise(rv);
289
+
290
+ return self;
291
+ }
292
+
293
+ static VALUE
294
+ pkcs11_C_InitPIN(VALUE self, VALUE session, VALUE pin)
295
+ {
296
+ CK_RV rv;
297
+ CK_C_InitPIN func;
298
+
299
+ StringValue(pin);
300
+ GetFunction(self, C_InitPIN, func);
301
+ rv = func(NUM2HANDLE(session),
302
+ (CK_UTF8CHAR_PTR)RSTRING_PTR(pin), RSTRING_LEN(pin));
303
+ if (rv != CKR_OK) pkcs11_raise(rv);
304
+
305
+ return self;
306
+ }
307
+
308
+ static VALUE
309
+ pkcs11_C_OpenSession(VALUE self, VALUE slot_id, VALUE flags)
310
+ {
311
+ CK_C_OpenSession func;
312
+ CK_RV rv;
313
+ CK_SESSION_HANDLE handle;
314
+
315
+ GetFunction(self, C_OpenSession, func);
316
+ rv = func(NUM2HANDLE(slot_id), NUM2ULONG(flags), 0, 0, &handle);
317
+ if(rv != CKR_OK) pkcs11_raise(rv);
318
+
319
+ return HANDLE2NUM(handle);
320
+ }
321
+
322
+ static VALUE
323
+ pkcs11_C_Login(VALUE self, VALUE session, VALUE user_type, VALUE pin)
324
+ {
325
+ CK_C_Login func;
326
+ CK_RV rv;
327
+
328
+ StringValue(pin);
329
+ GetFunction(self, C_Login, func);
330
+ rv = func(NUM2HANDLE(session), NUM2ULONG(user_type),
331
+ (CK_UTF8CHAR_PTR)RSTRING_PTR(pin), RSTRING_LEN(pin));
332
+ if(rv != CKR_OK) pkcs11_raise(rv);
333
+
334
+ return self;
335
+ }
336
+
337
+ static VALUE
338
+ pkcs11_C_Logout(VALUE self, VALUE session)
339
+ {
340
+ CK_C_Logout func;
341
+ CK_RV rv;
342
+
343
+ GetFunction(self, C_Logout, func);
344
+ rv = func(NUM2HANDLE(session));
345
+ if(rv != CKR_OK) pkcs11_raise(rv);
346
+
347
+ return self;
348
+ }
349
+
350
+ static VALUE
351
+ pkcs11_C_CloseSession(VALUE self, VALUE session)
352
+ {
353
+ CK_C_CloseSession func;
354
+ CK_RV rv;
355
+
356
+ GetFunction(self, C_CloseSession, func);
357
+ rv = func(NUM2HANDLE(session));
358
+ if(rv != CKR_OK) pkcs11_raise(rv);
359
+
360
+ return self;
361
+ }
362
+
363
+ static VALUE
364
+ pkcs11_C_CloseAllSessions(VALUE self, VALUE slot_id)
365
+ {
366
+ CK_C_CloseAllSessions func;
367
+ CK_RV rv;
368
+
369
+ GetFunction(self, C_CloseAllSessions, func);
370
+ rv = func(NUM2HANDLE(slot_id));
371
+ if(rv != CKR_OK) pkcs11_raise(rv);
372
+
373
+ return self;
374
+ }
375
+
376
+ static VALUE
377
+ pkcs11_C_GetSessionInfo(VALUE self, VALUE session)
378
+ {
379
+ CK_RV rv;
380
+ CK_C_GetSessionInfo func;
381
+ VALUE info;
382
+
383
+ info = pkcs11_new_struct(cCK_SESSION_INFO);
384
+ GetFunction(self, C_GetSessionInfo, func);
385
+ rv = func(NUM2HANDLE(session), DATA_PTR(info));
386
+ if (rv != CKR_OK) pkcs11_raise(rv);
387
+
388
+ return info;
389
+ }
390
+
391
+ static VALUE
392
+ pkcs11_C_GetOperationState(VALUE self, VALUE session)
393
+ {
394
+ CK_RV rv;
395
+ CK_C_GetOperationState func;
396
+ VALUE state;
397
+ CK_ULONG size;
398
+
399
+ GetFunction(self, C_GetOperationState, func);
400
+ rv = func(NUM2HANDLE(session), NULL_PTR, &size);
401
+ if (rv != CKR_OK) pkcs11_raise(rv);
402
+ state = rb_str_new(0, size);
403
+ rv = func(NUM2HANDLE(session), (CK_BYTE_PTR)RSTRING_PTR(state), &size);
404
+ if (rv != CKR_OK) pkcs11_raise(rv);
405
+
406
+ return state;
407
+ }
408
+
409
+ static VALUE
410
+ pkcs11_C_SetOperationState(VALUE self, VALUE session, VALUE state, VALUE enc_key, VALUE auth_key)
411
+ {
412
+ CK_RV rv;
413
+ CK_C_SetOperationState func;
414
+
415
+ StringValue(state);
416
+ GetFunction(self, C_SetOperationState, func);
417
+ rv = func(NUM2HANDLE(session),
418
+ (CK_BYTE_PTR)RSTRING_PTR(state), RSTRING_LEN(state),
419
+ NUM2HANDLE(state), NUM2HANDLE(auth_key));
420
+ if (rv != CKR_OK) pkcs11_raise(rv);
421
+
422
+ return self;
423
+ }
424
+
425
+ static VALUE
426
+ pkcs11_C_SetPIN(VALUE self, VALUE session, VALUE old_pin, VALUE new_pin)
427
+ {
428
+ CK_C_SetPIN func;
429
+ CK_RV rv;
430
+
431
+ StringValue(old_pin);
432
+ StringValue(new_pin);
433
+ GetFunction(self, C_SetPIN, func);
434
+ rv = func(NUM2HANDLE(session),
435
+ (CK_UTF8CHAR_PTR)RSTRING_PTR(old_pin), RSTRING_LEN(old_pin),
436
+ (CK_UTF8CHAR_PTR)RSTRING_PTR(new_pin), RSTRING_LEN(new_pin));
437
+ if(rv != CKR_OK) pkcs11_raise(rv);
438
+
439
+ return self;
440
+ }
441
+
442
+ static CK_ATTRIBUTE*
443
+ pkcs11_attr_ary2buf(VALUE template)
444
+ {
445
+ int i;
446
+ CK_ATTRIBUTE *tmp;
447
+
448
+ Check_Type(template, T_ARRAY);
449
+ tmp = (CK_ATTRIBUTE*)
450
+ malloc(sizeof(CK_ATTRIBUTE)*RARRAY_LEN(template));
451
+ if (!tmp) rb_sys_fail(0);
452
+ for (i = 0; i < RARRAY_LEN(template); i++){
453
+ VALUE attr = rb_ary_entry(template, i);
454
+ if (!rb_obj_is_kind_of(attr, cCK_ATTRIBUTE)) {
455
+ free(tmp);
456
+ rb_raise(rb_eArgError, "templates must be an ary of PKCS11::CK_ATTRIBUTE");
457
+ }
458
+ memcpy(tmp+i, DATA_PTR(attr), sizeof(CK_ATTRIBUTE));
459
+ }
460
+
461
+ return tmp;
462
+ }
463
+
464
+ static VALUE
465
+ pkcs11_C_CreateObject(VALUE self, VALUE session, VALUE template)
466
+ {
467
+ CK_C_CreateObject func;
468
+ CK_RV rv;
469
+ CK_ATTRIBUTE *tmp;
470
+ CK_OBJECT_HANDLE handle;
471
+
472
+ tmp = pkcs11_attr_ary2buf(template);
473
+ GetFunction(self, C_CreateObject, func);
474
+ rv = func(NUM2HANDLE(session), tmp, RARRAY_LEN(template), &handle);
475
+ free(tmp);
476
+ if(rv != CKR_OK) pkcs11_raise(rv);
477
+
478
+ return HANDLE2NUM(handle);
479
+ }
480
+
481
+ static VALUE
482
+ pkcs11_C_DestroyObject(VALUE self, VALUE session, VALUE handle)
483
+ {
484
+ CK_C_DestroyObject func;
485
+ CK_RV rv;
486
+
487
+ GetFunction(self, C_DestroyObject, func);
488
+ rv = func(NUM2HANDLE(session), NUM2HANDLE(handle));
489
+ if(rv != CKR_OK) pkcs11_raise(rv);
490
+
491
+ return self;
492
+ }
493
+
494
+ static VALUE
495
+ pkcs11_C_GetObjectSize(VALUE self, VALUE session, VALUE handle)
496
+ {
497
+ CK_C_GetObjectSize func;
498
+ CK_RV rv;
499
+ CK_ULONG size;
500
+
501
+ GetFunction(self, C_GetObjectSize, func);
502
+ rv = func(NUM2HANDLE(session), NUM2HANDLE(handle), &size);
503
+ if(rv != CKR_OK) pkcs11_raise(rv);
504
+
505
+ return ULONG2NUM(size);
506
+ }
507
+
508
+ static VALUE
509
+ pkcs11_C_FindObjectsInit(VALUE self, VALUE session, VALUE template)
510
+ {
511
+ CK_C_FindObjectsInit func;
512
+ CK_RV rv;
513
+ CK_ATTRIBUTE_PTR tmp = NULL_PTR;
514
+ CK_ULONG tmp_size = 0;
515
+
516
+ if (!NIL_P(template)){
517
+ tmp = pkcs11_attr_ary2buf(template);
518
+ tmp_size = RARRAY_LEN(template);
519
+ }
520
+ GetFunction(self, C_FindObjectsInit, func);
521
+ rv = func(NUM2HANDLE(session), tmp, tmp_size);
522
+ free(tmp);
523
+ if(rv != CKR_OK) pkcs11_raise(rv);
524
+
525
+ return self;
526
+ }
527
+
528
+ static VALUE
529
+ pkcs11_C_FindObjectsFinal(VALUE self, VALUE session)
530
+ {
531
+ CK_C_FindObjectsFinal func;
532
+ CK_RV rv;
533
+
534
+ GetFunction(self, C_FindObjectsFinal, func);
535
+ rv = func(NUM2HANDLE(session));
536
+ if(rv != CKR_OK) pkcs11_raise(rv);
537
+
538
+ return self;
539
+ }
540
+
541
+ static VALUE
542
+ pkcs11_C_FindObjects(VALUE self, VALUE session, VALUE max_count)
543
+ {
544
+ CK_C_FindObjects func;
545
+ CK_RV rv;
546
+ CK_OBJECT_HANDLE_PTR handles;
547
+ CK_ULONG count = 0;
548
+ VALUE ary;
549
+ int i;
550
+
551
+ handles = (CK_OBJECT_HANDLE_PTR)
552
+ malloc(sizeof(CK_OBJECT_HANDLE)*NUM2ULONG(max_count));
553
+ GetFunction(self, C_FindObjects, func);
554
+ rv = func(NUM2HANDLE(session), handles, NUM2ULONG(max_count), &count);
555
+ if(rv != CKR_OK){
556
+ free(handles);
557
+ pkcs11_raise(rv);
558
+ }
559
+ ary = rb_ary_new();
560
+ for(i = 0; i < count; i++)
561
+ rb_ary_push(ary, HANDLE2NUM(*(handles+i)));
562
+ free(handles);
563
+
564
+ return ary;
565
+ }
566
+
567
+ static VALUE ck_attr_s_alloc(VALUE);
568
+
569
+ static VALUE
570
+ pkcs11_C_GetAttributeValue(VALUE self, VALUE session, VALUE handle, VALUE template)
571
+ {
572
+ CK_C_GetAttributeValue func;
573
+ CK_RV rv;
574
+ CK_ULONG i, template_size;
575
+ CK_ATTRIBUTE_PTR tmp;
576
+ VALUE ary;
577
+
578
+ tmp = pkcs11_attr_ary2buf(template);
579
+ template_size = RARRAY_LEN(template);
580
+ GetFunction(self, C_GetAttributeValue, func);
581
+ rv = func(NUM2HANDLE(session), NUM2HANDLE(handle), tmp, template_size);
582
+ if(rv != CKR_OK){
583
+ free(tmp);
584
+ pkcs11_raise(rv);
585
+ }
586
+
587
+ for (i = 0; i < template_size; i++){
588
+ CK_ATTRIBUTE_PTR attr = tmp + i;
589
+ if (attr->ulValueLen != -1)
590
+ attr->pValue = (CK_BYTE_PTR)malloc(attr->ulValueLen);
591
+ }
592
+ rv = func(NUM2HANDLE(session), NUM2HANDLE(handle), tmp, template_size);
593
+ if(rv != CKR_OK){
594
+ for (i = 0; i < template_size; i++){
595
+ CK_ATTRIBUTE_PTR attr = tmp + i;
596
+ if (attr->pValue) free(attr->pValue);
597
+ }
598
+ free(tmp);
599
+ pkcs11_raise(rv);
600
+ }
601
+ ary = rb_ary_new();
602
+ for (i = 0; i < template_size; i++){
603
+ CK_ATTRIBUTE_PTR attr = tmp + i;
604
+ if (attr->ulValueLen != -1){
605
+ VALUE v = pkcs11_new_struct(cCK_ATTRIBUTE);
606
+ memcpy(DATA_PTR(v), attr, sizeof(CK_ATTRIBUTE));
607
+ rb_ary_push(ary, v);
608
+ }
609
+ }
610
+ free(tmp);
611
+
612
+ return ary;
613
+ }
614
+
615
+ static VALUE
616
+ pkcs11_C_SetAttributeValue(VALUE self, VALUE session, VALUE handle, VALUE template)
617
+ {
618
+ CK_C_SetAttributeValue func;
619
+ CK_RV rv;
620
+ CK_ATTRIBUTE *tmp;
621
+ CK_ULONG template_size;
622
+
623
+ tmp = pkcs11_attr_ary2buf(template);
624
+ template_size = RARRAY_LEN(template);
625
+ GetFunction(self, C_SetAttributeValue, func);
626
+ rv = func(NUM2HANDLE(session), NUM2HANDLE(handle), tmp, template_size);
627
+ free(tmp);
628
+ if(rv != CKR_OK) pkcs11_raise(rv);
629
+
630
+ return self;
631
+ }
632
+
633
+ static VALUE
634
+ pkcs11_C_SeedRandom(VALUE self, VALUE session, VALUE seed)
635
+ {
636
+ CK_C_SeedRandom func;
637
+ CK_RV rv;
638
+
639
+ GetFunction(self, C_SeedRandom, func);
640
+ rv = func(NUM2HANDLE(session),
641
+ (CK_BYTE_PTR)RSTRING_PTR(seed), RSTRING_LEN(seed));
642
+ if(rv != CKR_OK) pkcs11_raise(rv);
643
+
644
+ return self;
645
+ }
646
+
647
+ static VALUE
648
+ pkcs11_C_GenerateRandom(VALUE self, VALUE session, VALUE size)
649
+ {
650
+ CK_C_GenerateRandom func;
651
+ CK_ULONG sz = NUM2ULONG(size);
652
+ VALUE buf = rb_str_new(0, sz);
653
+ CK_RV rv;
654
+
655
+ GetFunction(self, C_GenerateRandom, func);
656
+ rv = func(NUM2HANDLE(session), (CK_BYTE_PTR)RSTRING_PTR(buf), sz);
657
+ if(rv != CKR_OK) pkcs11_raise(rv);
658
+
659
+ return buf;
660
+ }
661
+
662
+ static VALUE
663
+ pkcs11_C_WaitForSlotEvent(VALUE self, VALUE flags)
664
+ {
665
+ CK_C_WaitForSlotEvent func;
666
+ CK_RV rv;
667
+ CK_SLOT_ID slot_id;
668
+
669
+ GetFunction(self, C_WaitForSlotEvent, func);
670
+ rv = func(NUM2ULONG(flags), &slot_id, NULL_PTR);
671
+ if(rv == CKR_NO_EVENT) return Qnil;
672
+ if(rv != CKR_OK) pkcs11_raise(rv);
673
+
674
+ return HANDLE2NUM(slot_id);
675
+ }
676
+
677
+ ///////////////////////////////////////
678
+
679
+ typedef VALUE (*init_func)
680
+ (CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE);
681
+ typedef VALUE (*crypt_func)
682
+ (CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR);
683
+ typedef VALUE (*crypt_update_func)
684
+ (CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR);
685
+ typedef VALUE (*crypt_final_func)
686
+ (CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR);
687
+ typedef VALUE (*sign_update_func)
688
+ (CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG);
689
+ typedef VALUE (*verify_func)
690
+ (CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG);
691
+ typedef VALUE (*verify_final_func)
692
+ (CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG);
693
+
694
+ #define common_crypt(s, d, sz, f) common_crypt_update(s, d, sz, f)
695
+
696
+ static VALUE
697
+ common_init(VALUE session, VALUE mechanism, VALUE key, init_func func)
698
+ {
699
+ CK_RV rv;
700
+ CK_MECHANISM_PTR m;
701
+
702
+ if (!rb_obj_is_kind_of(mechanism, cCK_MECHANISM))
703
+ rb_raise(rb_eArgError, "2nd arg must be a PKCS11::CK_MECHANISM");
704
+ m = DATA_PTR(mechanism);
705
+ rv = func(NUM2HANDLE(session), m, NUM2HANDLE(key));
706
+ if(rv != CKR_OK) pkcs11_raise(rv);
707
+
708
+ return Qnil;
709
+ }
710
+
711
+ static VALUE
712
+ common_crypt_update(VALUE session, VALUE data, VALUE size, crypt_update_func func)
713
+ {
714
+ CK_RV rv;
715
+ CK_ULONG sz = 0;
716
+ VALUE buf;
717
+
718
+ StringValue(data);
719
+ if (NIL_P(size)){
720
+ rv = func(NUM2HANDLE(session),
721
+ (CK_BYTE_PTR)RSTRING_PTR(data), RSTRING_LEN(data),
722
+ NULL_PTR, &sz);
723
+ if(rv != CKR_OK) pkcs11_raise(rv);
724
+ }else{
725
+ sz = NUM2ULONG(size);
726
+ }
727
+ buf = rb_str_new(0, sz);
728
+
729
+ rv = func(NUM2HANDLE(session),
730
+ (CK_BYTE_PTR)RSTRING_PTR(data), RSTRING_LEN(data),
731
+ (CK_BYTE_PTR)RSTRING_PTR(buf), &sz);
732
+ if(rv != CKR_OK) pkcs11_raise(rv);
733
+ rb_str_set_len(buf, sz);
734
+
735
+ return buf;
736
+ }
737
+
738
+ static VALUE
739
+ common_crypt_final(VALUE session, VALUE size, crypt_final_func func)
740
+ {
741
+ CK_RV rv;
742
+ CK_ULONG sz = 0;
743
+ VALUE buf;
744
+
745
+ if (NIL_P(size)){
746
+ rv = func(NUM2HANDLE(session), NULL_PTR, &sz);
747
+ if(rv != CKR_OK) pkcs11_raise(rv);
748
+ }else{
749
+ sz = NUM2ULONG(size);
750
+ }
751
+ buf = rb_str_new(0, sz);
752
+
753
+ rv = func(NUM2HANDLE(session), (CK_BYTE_PTR)RSTRING_PTR(buf), &sz);
754
+ if(rv != CKR_OK) pkcs11_raise(rv);
755
+ rb_str_set_len(buf, sz);
756
+
757
+ return buf;
758
+ }
759
+
760
+ static VALUE
761
+ common_sign_update(VALUE session, VALUE data, sign_update_func func)
762
+ {
763
+ CK_RV rv;
764
+
765
+ StringValue(data);
766
+ rv = func(NUM2HANDLE(session),
767
+ (CK_BYTE_PTR)RSTRING_PTR(data), RSTRING_LEN(data));
768
+ if(rv != CKR_OK) pkcs11_raise(rv);
769
+
770
+ return Qnil;
771
+ }
772
+
773
+ static VALUE
774
+ common_verify(VALUE session, VALUE data, VALUE sig, verify_func func)
775
+ {
776
+ CK_RV rv;
777
+
778
+ StringValue(data);
779
+ StringValue(sig);
780
+ rv = func(NUM2HANDLE(session),
781
+ (CK_BYTE_PTR)RSTRING_PTR(data), RSTRING_LEN(data),
782
+ (CK_BYTE_PTR)RSTRING_PTR(sig), RSTRING_LEN(sig));
783
+ if(rv != CKR_OK) pkcs11_raise(rv);
784
+
785
+ return Qnil;
786
+ }
787
+
788
+ ////
789
+
790
+ static VALUE
791
+ pkcs11_C_EncryptInit(VALUE self, VALUE session, VALUE mechanism, VALUE key)
792
+ {
793
+ CK_C_EncryptInit func;
794
+ GetFunction(self, C_EncryptInit, func);
795
+ common_init(session, mechanism, key, func);
796
+ return self;
797
+ }
798
+
799
+ static VALUE
800
+ pkcs11_C_Encrypt(VALUE self, VALUE session, VALUE data, VALUE size)
801
+ {
802
+ CK_C_Encrypt func;
803
+ GetFunction(self, C_Encrypt, func);
804
+ return common_crypt(session, data, size, func);
805
+ }
806
+
807
+ static VALUE
808
+ pkcs11_C_EncryptUpdate(VALUE self, VALUE session, VALUE data, VALUE size)
809
+ {
810
+ CK_C_EncryptUpdate func;
811
+ GetFunction(self, C_EncryptUpdate, func);
812
+ return common_crypt_update(session, data, size, func);
813
+ }
814
+
815
+ static VALUE
816
+ pkcs11_C_EncryptFinal(VALUE self, VALUE session, VALUE size)
817
+ {
818
+ CK_C_EncryptFinal func;
819
+ GetFunction(self, C_EncryptFinal, func);
820
+ return common_crypt_final(session, size, func);
821
+ }
822
+
823
+ static VALUE
824
+ pkcs11_C_DecryptInit(VALUE self, VALUE session, VALUE mechanism, VALUE key)
825
+ {
826
+ CK_C_DecryptInit func;
827
+ GetFunction(self, C_DecryptInit, func);
828
+ common_init(session, mechanism, key, func);
829
+ return self;
830
+ }
831
+
832
+ static VALUE
833
+ pkcs11_C_Decrypt(VALUE self, VALUE session, VALUE data, VALUE size)
834
+ {
835
+ CK_C_Decrypt func;
836
+ GetFunction(self, C_Decrypt, func);
837
+ return common_crypt(session, data, size, func);
838
+ }
839
+
840
+ static VALUE
841
+ pkcs11_C_DecryptUpdate(VALUE self, VALUE session, VALUE data, VALUE size)
842
+ {
843
+ CK_C_DecryptUpdate func;
844
+ GetFunction(self, C_DecryptUpdate, func);
845
+ return common_crypt_update(session, data, size, func);
846
+ }
847
+
848
+ static VALUE
849
+ pkcs11_C_DecryptFinal(VALUE self, VALUE session, VALUE size)
850
+ {
851
+ CK_C_DecryptFinal func;
852
+ GetFunction(self, C_DecryptFinal, func);
853
+ return common_crypt_final(session, size, func);
854
+ }
855
+
856
+ #define common_sign(s, d, sz, f) common_crypt(s, d, sz, f)
857
+ #define common_sign_final(s, sz, f) common_crypt_final(s, sz, f)
858
+ #define common_verify_update(s, d, f) common_sign_update(s, d, f)
859
+ #define common_verify_final(s, d, f) common_sign_update(s, d, f)
860
+ #define common_verify_recover(s, d, sz, f) common_sign(s, d, sz, f)
861
+
862
+ static VALUE
863
+ pkcs11_C_SignInit(VALUE self, VALUE session, VALUE mechanism, VALUE key)
864
+ {
865
+ CK_C_SignInit func;
866
+ GetFunction(self, C_SignInit, func);
867
+ common_init(session, mechanism, key, func);
868
+ return self;
869
+ }
870
+
871
+ static VALUE
872
+ pkcs11_C_Sign(VALUE self, VALUE session, VALUE data, VALUE size)
873
+ {
874
+ CK_C_Sign func;
875
+ GetFunction(self, C_Sign, func);
876
+ return common_sign(session, data, size, func);
877
+ }
878
+
879
+ static VALUE
880
+ pkcs11_C_SignUpdate(VALUE self, VALUE session, VALUE data)
881
+ {
882
+ CK_C_SignUpdate func;
883
+ GetFunction(self, C_SignUpdate, func);
884
+ common_sign_update(session, data, func);
885
+ return self;
886
+ }
887
+
888
+ static VALUE
889
+ pkcs11_C_SignFinal(VALUE self, VALUE session, VALUE size)
890
+ {
891
+ CK_C_SignFinal func;
892
+ GetFunction(self, C_SignFinal, func);
893
+ return common_sign_final(session, size, func);
894
+ }
895
+
896
+ static VALUE
897
+ pkcs11_C_SignRecoverInit(VALUE self, VALUE session, VALUE mechanism, VALUE key)
898
+ {
899
+ CK_C_SignRecoverInit func;
900
+ GetFunction(self, C_SignRecoverInit, func);
901
+ common_init(session, mechanism, key, func);
902
+ return self;
903
+ }
904
+
905
+ static VALUE
906
+ pkcs11_C_SignRecover(VALUE self, VALUE session, VALUE data, VALUE size)
907
+ {
908
+ CK_C_SignRecover func;
909
+ GetFunction(self, C_SignRecover, func);
910
+ return common_sign(session, data, size, func);
911
+ }
912
+
913
+ static VALUE
914
+ pkcs11_C_VerifyInit(VALUE self, VALUE session, VALUE mechanism, VALUE key)
915
+ {
916
+ CK_C_VerifyInit func;
917
+ GetFunction(self, C_VerifyInit, func);
918
+ common_init(session, mechanism, key, func);
919
+ return self;
920
+ }
921
+
922
+ static VALUE
923
+ pkcs11_C_Verify(VALUE self, VALUE session, VALUE data, VALUE sig)
924
+ {
925
+ CK_C_Verify func;
926
+ GetFunction(self, C_Verify, func);
927
+ common_verify(session, data, sig, func);
928
+ return Qtrue;
929
+ }
930
+
931
+ static VALUE
932
+ pkcs11_C_VerifyUpdate(VALUE self, VALUE session, VALUE data)
933
+ {
934
+ CK_C_VerifyUpdate func;
935
+ GetFunction(self, C_VerifyUpdate, func);
936
+ common_verify_update(session, data, func);
937
+ return self;
938
+ }
939
+
940
+ static VALUE
941
+ pkcs11_C_VerifyFinal(VALUE self, VALUE session, VALUE sig)
942
+ {
943
+ CK_C_VerifyFinal func;
944
+ GetFunction(self, C_VerifyFinal, func);
945
+ common_verify_final(session, sig, func);
946
+ return Qtrue;
947
+ }
948
+
949
+ static VALUE
950
+ pkcs11_C_VerifyRecoverInit(VALUE self, VALUE session, VALUE mechanism, VALUE key)
951
+ {
952
+ CK_C_VerifyRecoverInit func;
953
+ GetFunction(self, C_VerifyRecoverInit, func);
954
+ common_init(session, mechanism, key, func);
955
+ return self;
956
+ }
957
+
958
+ static VALUE
959
+ pkcs11_C_VerifyRecover(VALUE self, VALUE session, VALUE sig, VALUE size)
960
+ {
961
+ CK_C_VerifyRecover func;
962
+ GetFunction(self, C_VerifyRecover, func);
963
+ common_verify_recover(session, sig, size, func);
964
+ return Qtrue;
965
+ }
966
+
967
+ #define common_digest(s, d, sz, f) common_crypt(s, d, sz, f)
968
+ #define common_digest_update(s, d, f) common_sign_update(s, d, f)
969
+ #define common_digest_final(s, sz, f) common_crypt_final(s, sz, f)
970
+
971
+ VALUE
972
+ pkcs11_C_DigestInit(VALUE self, VALUE session, VALUE mechanism)
973
+ {
974
+ CK_C_DigestInit func;
975
+ CK_MECHANISM_PTR m;
976
+ CK_RV rv;
977
+
978
+ GetFunction(self, C_DigestInit, func);
979
+ if (!rb_obj_is_kind_of(mechanism, cCK_MECHANISM))
980
+ rb_raise(rb_eArgError, "2nd arg must be a PKCS11::CK_MECHANISM");
981
+ m = DATA_PTR(mechanism);
982
+ rv = func(NUM2HANDLE(session), m);
983
+ if(rv != CKR_OK) pkcs11_raise(rv);
984
+
985
+ return self;
986
+ }
987
+
988
+ VALUE
989
+ pkcs11_C_Digest(VALUE self, VALUE session, VALUE data, VALUE size)
990
+ {
991
+ CK_C_Digest func;
992
+ GetFunction(self, C_Digest, func);
993
+ return common_digest(session, data, size, func);
994
+ }
995
+
996
+ VALUE
997
+ pkcs11_C_DigestUpdate(VALUE self, VALUE session, VALUE data)
998
+ {
999
+ CK_C_DigestUpdate func;
1000
+ GetFunction(self, C_DigestUpdate, func);
1001
+ common_digest_update(session, data, func);
1002
+ return self;
1003
+ }
1004
+
1005
+ VALUE
1006
+ pkcs11_C_DigestKey(VALUE self, VALUE session, VALUE handle)
1007
+ {
1008
+ CK_C_DigestKey func;
1009
+ CK_RV rv;
1010
+
1011
+ GetFunction(self, C_DigestKey, func);
1012
+ rv = func(NUM2HANDLE(session), NUM2HANDLE(handle));
1013
+ if(rv != CKR_OK) pkcs11_raise(rv);
1014
+
1015
+ return self;
1016
+ }
1017
+
1018
+ VALUE
1019
+ pkcs11_C_DigestFinal(VALUE self, VALUE session, VALUE size)
1020
+ {
1021
+ CK_C_DigestFinal func;
1022
+ GetFunction(self, C_DigestFinal, func);
1023
+ return common_digest_final(session, size, func);
1024
+ }
1025
+
1026
+ VALUE
1027
+ pkcs11_C_DigestEncryptUpdate(VALUE self, VALUE session, VALUE data, VALUE size)
1028
+ {
1029
+ CK_C_DigestEncryptUpdate func;
1030
+ GetFunction(self, C_DigestEncryptUpdate, func);
1031
+ return common_crypt_update(session, data, size, func);
1032
+ }
1033
+
1034
+ VALUE
1035
+ pkcs11_C_DecryptDigestUpdate(VALUE self, VALUE session, VALUE data, VALUE size)
1036
+ {
1037
+ CK_C_DecryptDigestUpdate func;
1038
+ GetFunction(self, C_DecryptDigestUpdate, func);
1039
+ return common_crypt_update(session, data, size, func);
1040
+ }
1041
+
1042
+ VALUE
1043
+ pkcs11_C_SignEncryptUpdate(VALUE self, VALUE session, VALUE data, VALUE size)
1044
+ {
1045
+ CK_C_SignEncryptUpdate func;
1046
+ GetFunction(self, C_SignEncryptUpdate, func);
1047
+ return common_crypt_update(session, data, size, func);
1048
+ }
1049
+
1050
+ VALUE
1051
+ pkcs11_C_DecryptVerifyUpdate(VALUE self, VALUE session, VALUE data, VALUE size)
1052
+ {
1053
+ CK_C_DecryptVerifyUpdate func;
1054
+ GetFunction(self, C_DecryptVerifyUpdate, func);
1055
+ return common_crypt_update(session, data, size, func);
1056
+ }
1057
+
1058
+ VALUE
1059
+ pkcs11_C_GenerateKey(VALUE self, VALUE session, VALUE mechanism, VALUE template){
1060
+ CK_C_GenerateKey func;
1061
+ CK_ATTRIBUTE_PTR tmp;
1062
+ CK_OBJECT_HANDLE handle;
1063
+ CK_MECHANISM_PTR m;
1064
+ CK_RV rv;
1065
+
1066
+ GetFunction(self, C_GenerateKey, func);
1067
+ if (!rb_obj_is_kind_of(mechanism, cCK_MECHANISM))
1068
+ rb_raise(rb_eArgError, "2nd arg must be a PKCS11::CK_MECHANISM");
1069
+ m = DATA_PTR(mechanism);
1070
+ tmp = pkcs11_attr_ary2buf(template);
1071
+ rv = func(NUM2HANDLE(session), m, tmp, RARRAY_LEN(template), &handle);
1072
+ free(tmp);
1073
+ if(rv != CKR_OK) pkcs11_raise(rv);
1074
+
1075
+ return HANDLE2NUM(handle);
1076
+ }
1077
+
1078
+ VALUE
1079
+ pkcs11_C_GenerateKeyPair(VALUE self, VALUE session, VALUE mechanism, VALUE pubkey_template, VALUE privkey_template)
1080
+ {
1081
+ CK_C_GenerateKeyPair func;
1082
+ CK_ATTRIBUTE_PTR pubkey_tmp, privkey_tmp;
1083
+ CK_OBJECT_HANDLE pubkey_handle, privkey_handle;
1084
+ CK_MECHANISM_PTR m;
1085
+ CK_RV rv;
1086
+ VALUE ary;
1087
+
1088
+ GetFunction(self, C_GenerateKeyPair, func);
1089
+ if (!rb_obj_is_kind_of(mechanism, cCK_MECHANISM))
1090
+ rb_raise(rb_eArgError, "2nd arg must be a PKCS11::CK_MECHANISM");
1091
+ m = DATA_PTR(mechanism);
1092
+ pubkey_tmp = pkcs11_attr_ary2buf(pubkey_template);
1093
+ privkey_tmp = pkcs11_attr_ary2buf(privkey_template);
1094
+ rv = func(NUM2HANDLE(session), m,
1095
+ pubkey_tmp, RARRAY_LEN(pubkey_template),
1096
+ privkey_tmp, RARRAY_LEN(privkey_template),
1097
+ &pubkey_handle, &privkey_handle);
1098
+ free(pubkey_tmp);
1099
+ free(privkey_tmp);
1100
+ if(rv != CKR_OK) pkcs11_raise(rv);
1101
+ ary = rb_ary_new();
1102
+ rb_ary_push(ary, HANDLE2NUM(pubkey_handle));
1103
+ rb_ary_push(ary, HANDLE2NUM(privkey_handle));
1104
+
1105
+ return ary;
1106
+ }
1107
+
1108
+ VALUE
1109
+ pkcs11_C_WrapKey(VALUE self, VALUE session, VALUE mechanism, VALUE wrapping, VALUE wrapped, VALUE size)
1110
+ {
1111
+ CK_C_WrapKey func;
1112
+ CK_MECHANISM_PTR m;
1113
+ CK_ULONG sz = 0;
1114
+ VALUE buf;
1115
+ CK_RV rv;
1116
+
1117
+ GetFunction(self, C_WrapKey, func);
1118
+ if (!rb_obj_is_kind_of(mechanism, cCK_MECHANISM))
1119
+ rb_raise(rb_eArgError, "2nd arg must be a PKCS11::CK_MECHANISM");
1120
+ m = DATA_PTR(mechanism);
1121
+ if (NIL_P(size)){
1122
+ rv = func(NUM2HANDLE(session), m,
1123
+ NUM2HANDLE(wrapping), NUM2HANDLE(wrapped),
1124
+ (CK_BYTE_PTR)NULL_PTR, &sz);
1125
+ if(rv != CKR_OK) pkcs11_raise(rv);
1126
+ }else{
1127
+ sz = NUM2ULONG(size);
1128
+ }
1129
+ buf = rb_str_new(0, sz);
1130
+
1131
+ rv = func(NUM2HANDLE(session), m,
1132
+ NUM2HANDLE(wrapping), NUM2HANDLE(wrapped),
1133
+ (CK_BYTE_PTR)RSTRING_PTR(buf), &sz);
1134
+ if(rv != CKR_OK) pkcs11_raise(rv);
1135
+ rb_str_set_len(buf, sz);
1136
+
1137
+ return buf;
1138
+ }
1139
+
1140
+ VALUE
1141
+ pkcs11_C_UnwrapKey(VALUE self, VALUE session, VALUE mechanism, VALUE wrapping, VALUE wrapped, VALUE template)
1142
+ {
1143
+ CK_C_UnwrapKey func;
1144
+ CK_MECHANISM_PTR m;
1145
+ CK_ATTRIBUTE_PTR tmp;
1146
+ CK_OBJECT_HANDLE h;
1147
+ CK_RV rv;
1148
+
1149
+ GetFunction(self, C_UnwrapKey, func);
1150
+ if (!rb_obj_is_kind_of(mechanism, cCK_MECHANISM))
1151
+ rb_raise(rb_eArgError, "2nd arg must be a PKCS11::CK_MECHANISM");
1152
+ m = DATA_PTR(mechanism);
1153
+ tmp = pkcs11_attr_ary2buf(template);
1154
+ rv = func(NUM2HANDLE(session), m, NUM2HANDLE(wrapping),
1155
+ (CK_BYTE_PTR)RSTRING_PTR(wrapped), RSTRING_LEN(wrapped),
1156
+ tmp, RARRAY_LEN(template), &h);
1157
+ free(tmp);
1158
+ if(rv != CKR_OK) pkcs11_raise(rv);
1159
+
1160
+ return HANDLE2NUM(h);
1161
+ }
1162
+
1163
+ VALUE
1164
+ pkcs11_C_DeriveKey(VALUE self, VALUE session, VALUE mechanism, VALUE base, VALUE template)
1165
+ {
1166
+ CK_C_DeriveKey func;
1167
+ CK_MECHANISM_PTR m;
1168
+ CK_ATTRIBUTE_PTR tmp;
1169
+ CK_OBJECT_HANDLE h;
1170
+ CK_RV rv;
1171
+
1172
+ GetFunction(self, C_DeriveKey, func);
1173
+ if (!rb_obj_is_kind_of(mechanism, cCK_MECHANISM))
1174
+ rb_raise(rb_eArgError, "2nd arg must be a PKCS11::CK_MECHANISM");
1175
+ m = DATA_PTR(mechanism);
1176
+ tmp = pkcs11_attr_ary2buf(template);
1177
+ rv = func(NUM2HANDLE(session), m, NUM2HANDLE(base),
1178
+ tmp, RARRAY_LEN(template), &h);
1179
+ free(tmp);
1180
+ if(rv != CKR_OK) pkcs11_raise(rv);
1181
+
1182
+ return HANDLE2NUM(h);
1183
+ }
1184
+
1185
+ ///////////////////////////////////////
1186
+
1187
+ static void
1188
+ ck_attr_free(CK_ATTRIBUTE *attr)
1189
+ {
1190
+ if (attr->pValue) free(attr->pValue);
1191
+ free(attr);
1192
+ }
1193
+
1194
+ static VALUE
1195
+ ck_attr_s_alloc(VALUE self)
1196
+ {
1197
+ VALUE obj;
1198
+ CK_ATTRIBUTE *attr;
1199
+ obj = Data_Make_Struct(self, CK_ATTRIBUTE, 0, ck_attr_free, attr);
1200
+ return obj;
1201
+ }
1202
+
1203
+ static VALUE
1204
+ ck_attr_initialize(int argc, VALUE *argv, VALUE self)
1205
+ {
1206
+ VALUE type, value;
1207
+ CK_ATTRIBUTE *attr;
1208
+
1209
+ rb_scan_args(argc, argv, "02", &type, &value);
1210
+ Data_Get_Struct(self, CK_ATTRIBUTE, attr);
1211
+ if (argc == 0) return self;
1212
+ attr->type = NUM2HANDLE(type);
1213
+ attr->pValue = NULL;
1214
+ switch(TYPE(value)){
1215
+ case T_TRUE:
1216
+ attr->pValue = (CK_BYTE_PTR)malloc(sizeof(CK_BBOOL));
1217
+ *((CK_BBOOL*)attr->pValue) = TRUE;
1218
+ attr->ulValueLen = sizeof(CK_BBOOL);
1219
+ break;
1220
+ case T_FALSE:
1221
+ attr->pValue = (CK_BYTE_PTR)malloc(sizeof(CK_BBOOL));
1222
+ *((CK_BBOOL*)attr->pValue) = FALSE;
1223
+ attr->ulValueLen = sizeof(CK_BBOOL);
1224
+ break;
1225
+ case T_NIL:
1226
+ attr->pValue = (CK_BYTE_PTR)NULL;
1227
+ attr->ulValueLen = 0;
1228
+ break;
1229
+ case T_FIXNUM:
1230
+ attr->pValue = (CK_BYTE_PTR)malloc(sizeof(CK_OBJECT_CLASS));
1231
+ *((CK_OBJECT_CLASS*)attr->pValue) = NUM2ULONG(value);
1232
+ attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
1233
+ break;
1234
+ default:
1235
+ StringValue(value);
1236
+ attr->pValue = (CK_BYTE_PTR)malloc(RSTRING_LEN(value));
1237
+ memcpy(attr->pValue, RSTRING_PTR(value), RSTRING_LEN(value));
1238
+ attr->ulValueLen = RSTRING_LEN(value);
1239
+ break;
1240
+ }
1241
+ return self;
1242
+ }
1243
+
1244
+ static VALUE
1245
+ ck_attr_type(VALUE self)
1246
+ {
1247
+ CK_ATTRIBUTE *attr;
1248
+ Data_Get_Struct(self, CK_ATTRIBUTE, attr);
1249
+ return ULONG2NUM(attr->type);
1250
+ }
1251
+
1252
+ static VALUE
1253
+ ck_attr_value(VALUE self)
1254
+ {
1255
+ CK_ATTRIBUTE *attr;
1256
+ Data_Get_Struct(self, CK_ATTRIBUTE, attr);
1257
+ if (attr->ulValueLen == 0) return Qnil;
1258
+ switch(attr->type){
1259
+ case CKA_TOKEN:
1260
+ case CKA_PRIVATE:
1261
+ case CKA_SENSITIVE:
1262
+ case CKA_ENCRYPT:
1263
+ case CKA_DECRYPT:
1264
+ case CKA_WRAP:
1265
+ case CKA_UNWRAP:
1266
+ case CKA_SIGN:
1267
+ case CKA_SIGN_RECOVER:
1268
+ case CKA_VERIFY:
1269
+ case CKA_VERIFY_RECOVER:
1270
+ case CKA_DERIVE:
1271
+ case CKA_TRUSTED:
1272
+ case CKA_EXTRACTABLE:
1273
+ case CKA_LOCAL:
1274
+ case CKA_NEVER_EXTRACTABLE:
1275
+ case CKA_ALWAYS_SENSITIVE:
1276
+ case CKA_MODIFIABLE:
1277
+ case CKA_HAS_RESET:
1278
+ case CKA_ALWAYS_AUTHENTICATE:
1279
+ case CKA_COLOR:
1280
+ case CKA_OTP_USER_FRIENDLY_MODE:
1281
+ case CKA_WRAP_WITH_TRUSTED:
1282
+ if (attr->ulValueLen == sizeof(CK_BBOOL))
1283
+ return (*(CK_BBOOL*)(attr->pValue)) == CK_TRUE ? Qtrue : Qfalse;
1284
+ break;
1285
+ case CKA_CLASS:
1286
+ case CKA_CERTIFICATE_TYPE:
1287
+ case CKA_KEY_TYPE:
1288
+ case CKA_HW_FEATURE_TYPE:
1289
+ case CKA_BITS_PER_PIXEL:
1290
+ case CKA_CERTIFICATE_CATEGORY:
1291
+ case CKA_CHAR_COLUMNS:
1292
+ case CKA_CHAR_ROWS:
1293
+ case CKA_JAVA_MIDP_SECURITY_DOMAIN:
1294
+ case CKA_MECHANISM_TYPE:
1295
+ case CKA_OTP_SERVICE_LOGO_TYPE:
1296
+ case CKA_PIXEL_X:
1297
+ case CKA_PIXEL_Y:
1298
+ case CKA_RESOLUTION:
1299
+ if (attr->ulValueLen == sizeof(CK_ULONG))
1300
+ return ULONG2NUM(*(CK_ULONG_PTR)(attr->pValue));
1301
+ break;
1302
+ }
1303
+ return rb_str_new(attr->pValue, attr->ulValueLen);
1304
+ }
1305
+
1306
+ ///////////////////////////////////////
1307
+
1308
+ static VALUE
1309
+ get_string(VALUE obj, off_t offset, size_t size)
1310
+ {
1311
+ char *ptr = (char*)DATA_PTR(obj);
1312
+ return rb_str_new(ptr+offset, size);
1313
+ }
1314
+
1315
+ static VALUE
1316
+ set_string(VALUE obj, VALUE value, off_t offset, size_t size)
1317
+ {
1318
+ char *ptr = (char*)DATA_PTR(obj);
1319
+ int len = size;
1320
+ StringValue(value);
1321
+ if (RSTRING_LEN(value) < len) len = RSTRING_LEN(value);
1322
+ memset(ptr+offset, 0, size);
1323
+ memcpy(ptr+offset, RSTRING_PTR(value), len);
1324
+ return value;
1325
+ }
1326
+
1327
+ static VALUE
1328
+ get_ulong(VALUE obj, off_t offset)
1329
+ {
1330
+ char *ptr = (char*)DATA_PTR(obj);
1331
+ return ULONG2NUM(*(CK_ULONG_PTR)(ptr+offset));
1332
+ }
1333
+
1334
+ static VALUE
1335
+ set_ulong(VALUE obj, VALUE value, off_t offset)
1336
+ {
1337
+ char *ptr = (char*)DATA_PTR(obj);
1338
+ *(CK_ULONG_PTR)(ptr+offset) = NUM2ULONG(value);
1339
+ return value;
1340
+ }
1341
+
1342
+ static VALUE
1343
+ get_version(VALUE obj, off_t offset)
1344
+ {
1345
+ char *ptr = (char*)DATA_PTR(obj);
1346
+ CK_VERSION_PTR v;
1347
+ char buf[64];
1348
+ v = (CK_VERSION_PTR)(ptr+offset);
1349
+ snprintf(buf, sizeof(buf), "%d.%d", v->major, v->minor);
1350
+ return rb_str_new2(buf);
1351
+ }
1352
+
1353
+ static VALUE
1354
+ set_version(VALUE obj, VALUE value, off_t offset)
1355
+ {
1356
+ rb_notimplement();
1357
+ return Qnil;
1358
+ }
1359
+
1360
+ static VALUE
1361
+ get_string_ptr(VALUE obj, char *name, off_t offset)
1362
+ {
1363
+ char *ptr = (char*)DATA_PTR(obj);
1364
+ char *p = *(char**)(ptr+offset);
1365
+ if (!p) return Qnil;
1366
+ return rb_str_new2(p);
1367
+ }
1368
+
1369
+ static VALUE
1370
+ set_string_ptr(VALUE obj, VALUE value, char *name, off_t offset)
1371
+ {
1372
+ char *ptr = (char*)DATA_PTR(obj);
1373
+ rb_iv_set(obj, name, value);
1374
+ if (NIL_P(value)){
1375
+ *(CK_VOID_PTR*)(ptr+offset) = NULL_PTR;
1376
+ return value;
1377
+ }
1378
+ StringValue(value);
1379
+ value = rb_obj_freeze(rb_str_dup(value));
1380
+ *(CK_VOID_PTR*)(ptr+offset) = RSTRING_PTR(value);
1381
+ return value;
1382
+ }
1383
+
1384
+ #define OFFSET_OF(s, f) ((off_t)((char*)&(((s*)0)->f) - (char*)0))
1385
+ #define SIZE_OF(s, f) (sizeof(((s*)0)->f))
1386
+
1387
+ #define PKCS11_IMPLEMENT_ALLOCATOR(s) \
1388
+ static VALUE s##_s_alloc(VALUE self){ \
1389
+ s *info; \
1390
+ VALUE obj = Data_Make_Struct(self, s, 0, -1, info); \
1391
+ memset(info, 0, sizeof(s)); \
1392
+ return obj; \
1393
+ }
1394
+
1395
+ #define PKCS11_IMPLEMENT_STRING_ACCESSOR(s, f) \
1396
+ static VALUE c##s##_get_##f(VALUE o){ \
1397
+ return get_string(o, OFFSET_OF(s, f), SIZE_OF(s, f)); \
1398
+ } \
1399
+ static VALUE c##s##_set_##f(VALUE o, VALUE v){ \
1400
+ return set_string(o, v, OFFSET_OF(s, f), SIZE_OF(s, f)); \
1401
+ }
1402
+
1403
+ #define PKCS11_IMPLEMENT_ULONG_ACCESSOR(s, f) \
1404
+ static VALUE c##s##_get_##f(VALUE o){ \
1405
+ return get_ulong(o, OFFSET_OF(s, f)); \
1406
+ } \
1407
+ static VALUE c##s##_set_##f(VALUE o, VALUE v){ \
1408
+ return set_ulong(o, v, OFFSET_OF(s, f)); \
1409
+ }
1410
+
1411
+ #define PKCS11_IMPLEMENT_VERSION_ACCESSOR(s, f) \
1412
+ static VALUE c##s##_get_##f(VALUE o){ \
1413
+ return get_version(o, OFFSET_OF(s, f)); \
1414
+ } \
1415
+ static VALUE c##s##_set_##f(VALUE o, VALUE v){ \
1416
+ return set_version(o, v, OFFSET_OF(s, f)); \
1417
+ }
1418
+
1419
+ #define PKCS11_IMPLEMENT_STRING_PTR_ACCESSOR(s, f) \
1420
+ static VALUE c##s##_get_##f(VALUE o){ \
1421
+ return get_string_ptr(o, #f, OFFSET_OF(s, f)); \
1422
+ } \
1423
+ static VALUE c##s##_set_##f(VALUE o, VALUE v){ \
1424
+ return set_string_ptr(o, v, #f, OFFSET_OF(s, f)); \
1425
+ }
1426
+
1427
+ ///////////////////////////////////////
1428
+
1429
+ PKCS11_IMPLEMENT_ALLOCATOR(CK_C_INITIALIZE_ARGS)
1430
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_C_INITIALIZE_ARGS, flags)
1431
+ PKCS11_IMPLEMENT_STRING_PTR_ACCESSOR(CK_C_INITIALIZE_ARGS, pReserved)
1432
+
1433
+ PKCS11_IMPLEMENT_ALLOCATOR(CK_INFO)
1434
+ PKCS11_IMPLEMENT_VERSION_ACCESSOR(CK_INFO, cryptokiVersion)
1435
+ PKCS11_IMPLEMENT_STRING_ACCESSOR(CK_INFO, manufacturerID)
1436
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_INFO, flags)
1437
+ PKCS11_IMPLEMENT_STRING_ACCESSOR(CK_INFO, libraryDescription)
1438
+ PKCS11_IMPLEMENT_VERSION_ACCESSOR(CK_INFO, libraryVersion)
1439
+
1440
+ PKCS11_IMPLEMENT_ALLOCATOR(CK_SLOT_INFO)
1441
+ PKCS11_IMPLEMENT_STRING_ACCESSOR(CK_SLOT_INFO, slotDescription)
1442
+ PKCS11_IMPLEMENT_STRING_ACCESSOR(CK_SLOT_INFO, manufacturerID)
1443
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_SLOT_INFO, flags)
1444
+ PKCS11_IMPLEMENT_VERSION_ACCESSOR(CK_SLOT_INFO, hardwareVersion)
1445
+ PKCS11_IMPLEMENT_VERSION_ACCESSOR(CK_SLOT_INFO, firmwareVersion)
1446
+
1447
+ PKCS11_IMPLEMENT_ALLOCATOR(CK_TOKEN_INFO);
1448
+ PKCS11_IMPLEMENT_STRING_ACCESSOR(CK_TOKEN_INFO, label);
1449
+ PKCS11_IMPLEMENT_STRING_ACCESSOR(CK_TOKEN_INFO, manufacturerID);
1450
+ PKCS11_IMPLEMENT_STRING_ACCESSOR(CK_TOKEN_INFO, model);
1451
+ PKCS11_IMPLEMENT_STRING_ACCESSOR(CK_TOKEN_INFO, serialNumber);
1452
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, flags);
1453
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulMaxSessionCount);
1454
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulSessionCount);
1455
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulMaxRwSessionCount);
1456
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulRwSessionCount);
1457
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulMaxPinLen);
1458
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulMinPinLen);
1459
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulTotalPublicMemory);
1460
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulFreePublicMemory);
1461
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulTotalPrivateMemory);
1462
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_TOKEN_INFO, ulFreePrivateMemory);
1463
+ PKCS11_IMPLEMENT_VERSION_ACCESSOR(CK_TOKEN_INFO, hardwareVersion);
1464
+ PKCS11_IMPLEMENT_VERSION_ACCESSOR(CK_TOKEN_INFO, firmwareVersion);
1465
+ PKCS11_IMPLEMENT_STRING_ACCESSOR(CK_TOKEN_INFO, utcTime);
1466
+
1467
+ PKCS11_IMPLEMENT_ALLOCATOR(CK_MECHANISM_INFO);
1468
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_MECHANISM_INFO, ulMinKeySize);
1469
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_MECHANISM_INFO, ulMaxKeySize);
1470
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_MECHANISM_INFO, flags);
1471
+
1472
+ PKCS11_IMPLEMENT_ALLOCATOR(CK_SESSION_INFO);
1473
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_SESSION_INFO, slotID);
1474
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_SESSION_INFO, state);
1475
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_SESSION_INFO, flags);
1476
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_SESSION_INFO, ulDeviceError);
1477
+
1478
+ ///////////////////////////////////////
1479
+
1480
+ PKCS11_IMPLEMENT_ALLOCATOR(CK_MECHANISM)
1481
+
1482
+ static VALUE
1483
+ cCK_MECHANISM_initialize(int argc, VALUE *argv, VALUE self)
1484
+ {
1485
+ VALUE type, param;
1486
+
1487
+ rb_scan_args(argc, argv, "02", &type, &param);
1488
+ rb_funcall(self, rb_intern("mechanism="), 1, type);
1489
+ rb_funcall(self, rb_intern("pParameter="), 1, param);
1490
+
1491
+ return self;
1492
+ }
1493
+
1494
+ PKCS11_IMPLEMENT_ULONG_ACCESSOR(CK_MECHANISM, mechanism);
1495
+
1496
+ static VALUE
1497
+ cCK_MECHANISM_get_pParameter(VALUE self)
1498
+ {
1499
+ CK_MECHANISM_PTR m = DATA_PTR(self);
1500
+ if (!m->pParameter) return Qnil;
1501
+ else return rb_str_new(m->pParameter, m->ulParameterLen);
1502
+ }
1503
+
1504
+ static VALUE
1505
+ cCK_MECHANISM_set_pParameter(VALUE self, VALUE value)
1506
+ {
1507
+ CK_MECHANISM_PTR m = DATA_PTR(self);
1508
+
1509
+ if (NIL_P(value)){
1510
+ m->pParameter = NULL_PTR;
1511
+ m->ulParameterLen = 0;
1512
+ }
1513
+ else{
1514
+ StringValue(value);
1515
+ value = rb_obj_freeze(rb_str_dup(value));
1516
+ m->pParameter = RSTRING_PTR(value);
1517
+ m->ulParameterLen = RSTRING_LEN(value);
1518
+ }
1519
+ rb_iv_set(self, "pParameter", value);
1520
+
1521
+ return value;
1522
+ }
1523
+
1524
+ ///////////////////////////////////////
1525
+
1526
+ #define PKCS11_DEFINE_METHOD(name, args) \
1527
+ rb_define_method(cPKCS11, #name, pkcs11_##name, args);
1528
+
1529
+ #define PKCS11_DEFINE_STRUCT(s) \
1530
+ do { \
1531
+ c##s = rb_define_class_under(mPKCS11, #s, rb_cObject); \
1532
+ rb_define_alloc_func(c##s, s##_s_alloc); \
1533
+ } while(0)
1534
+
1535
+ #define PKCS11_DEFINE_MEMBER(s, f) \
1536
+ do { \
1537
+ rb_define_method(c##s, #f, c##s##_get_##f, 0); \
1538
+ rb_define_method(c##s, #f "=", c##s##_set_##f, 1); \
1539
+ } while(0)
1540
+
1541
+ void
1542
+ Init_pkcs11_ext()
1543
+ {
1544
+ mPKCS11 = rb_define_module("PKCS11");
1545
+ sNEW = rb_intern("new");
1546
+ cPKCS11 = rb_define_class_under(mPKCS11, "Library", rb_cObject);
1547
+
1548
+ /* Document-method: PKCS11.open
1549
+ *
1550
+ * Alias function for PKCS11::Library.new
1551
+ */
1552
+ rb_define_module_function(mPKCS11, "open", pkcs11_library_new, -1);
1553
+
1554
+ /* Library version */
1555
+ rb_define_const( mPKCS11, "VERSION", rb_str_new2(VERSION) );
1556
+
1557
+ ePKCS11Error = rb_define_class_under(mPKCS11, "Error", rb_eStandardError);
1558
+ rb_define_alloc_func(cPKCS11, pkcs11_s_alloc);
1559
+ rb_define_method(cPKCS11, "initialize", pkcs11_initialize, -1);
1560
+
1561
+ PKCS11_DEFINE_METHOD(C_GetInfo, 0);
1562
+ PKCS11_DEFINE_METHOD(C_GetSlotList, 1);
1563
+ PKCS11_DEFINE_METHOD(C_GetSlotInfo, 1);
1564
+ PKCS11_DEFINE_METHOD(C_GetTokenInfo, 1);
1565
+ PKCS11_DEFINE_METHOD(C_GetMechanismList, 1);
1566
+ PKCS11_DEFINE_METHOD(C_GetMechanismInfo, 2);
1567
+ PKCS11_DEFINE_METHOD(C_InitToken, 3);
1568
+ PKCS11_DEFINE_METHOD(C_InitPIN, 2);
1569
+
1570
+ PKCS11_DEFINE_METHOD(C_OpenSession, 2);
1571
+ PKCS11_DEFINE_METHOD(C_CloseSession, 1);
1572
+ PKCS11_DEFINE_METHOD(C_CloseAllSessions, 1);
1573
+ PKCS11_DEFINE_METHOD(C_GetSessionInfo, 1);
1574
+ PKCS11_DEFINE_METHOD(C_GetOperationState, 1);
1575
+ PKCS11_DEFINE_METHOD(C_SetOperationState, 4);
1576
+ PKCS11_DEFINE_METHOD(C_Login, 3);
1577
+ PKCS11_DEFINE_METHOD(C_Logout, 1);
1578
+ PKCS11_DEFINE_METHOD(C_SetPIN, 3);
1579
+
1580
+ PKCS11_DEFINE_METHOD(C_CreateObject, 2);
1581
+ PKCS11_DEFINE_METHOD(C_DestroyObject, 2);
1582
+ PKCS11_DEFINE_METHOD(C_GetObjectSize, 2);
1583
+ PKCS11_DEFINE_METHOD(C_FindObjectsInit, 2);
1584
+ PKCS11_DEFINE_METHOD(C_FindObjectsFinal, 1);
1585
+ PKCS11_DEFINE_METHOD(C_FindObjects, 2);
1586
+ PKCS11_DEFINE_METHOD(C_GetAttributeValue, 3);
1587
+ PKCS11_DEFINE_METHOD(C_SetAttributeValue, 3);
1588
+
1589
+ PKCS11_DEFINE_METHOD(C_EncryptInit, 3);
1590
+ PKCS11_DEFINE_METHOD(C_Encrypt, 3);
1591
+ PKCS11_DEFINE_METHOD(C_EncryptUpdate, 3);
1592
+ PKCS11_DEFINE_METHOD(C_EncryptFinal, 2);
1593
+ PKCS11_DEFINE_METHOD(C_DecryptInit, 3);
1594
+ PKCS11_DEFINE_METHOD(C_Decrypt, 3);
1595
+ PKCS11_DEFINE_METHOD(C_DecryptUpdate, 3);
1596
+ PKCS11_DEFINE_METHOD(C_DecryptFinal, 2);
1597
+ PKCS11_DEFINE_METHOD(C_DigestInit, 2);
1598
+ PKCS11_DEFINE_METHOD(C_Digest, 3);
1599
+ PKCS11_DEFINE_METHOD(C_DigestUpdate, 2);
1600
+ PKCS11_DEFINE_METHOD(C_DigestKey, 2);
1601
+ PKCS11_DEFINE_METHOD(C_DigestFinal, 2);
1602
+ PKCS11_DEFINE_METHOD(C_SignInit, 3);
1603
+ PKCS11_DEFINE_METHOD(C_Sign, 3);
1604
+ PKCS11_DEFINE_METHOD(C_SignUpdate, 2);
1605
+ PKCS11_DEFINE_METHOD(C_SignFinal, 2);
1606
+ PKCS11_DEFINE_METHOD(C_SignRecoverInit, 3);
1607
+ PKCS11_DEFINE_METHOD(C_SignRecover, 3);
1608
+ PKCS11_DEFINE_METHOD(C_VerifyInit, 3);
1609
+ PKCS11_DEFINE_METHOD(C_Verify, 3);
1610
+ PKCS11_DEFINE_METHOD(C_VerifyUpdate, 2);
1611
+ PKCS11_DEFINE_METHOD(C_VerifyFinal, 2);
1612
+ PKCS11_DEFINE_METHOD(C_VerifyRecoverInit, 3);
1613
+ PKCS11_DEFINE_METHOD(C_VerifyRecover, 3);
1614
+ PKCS11_DEFINE_METHOD(C_DigestEncryptUpdate, 3);
1615
+ PKCS11_DEFINE_METHOD(C_DecryptDigestUpdate, 3);
1616
+ PKCS11_DEFINE_METHOD(C_SignEncryptUpdate, 3);
1617
+ PKCS11_DEFINE_METHOD(C_DecryptVerifyUpdate, 3);
1618
+ PKCS11_DEFINE_METHOD(C_GenerateKey, 3);
1619
+ PKCS11_DEFINE_METHOD(C_GenerateKeyPair, 4);
1620
+ PKCS11_DEFINE_METHOD(C_WrapKey, 5);
1621
+ PKCS11_DEFINE_METHOD(C_UnwrapKey, 5);
1622
+ PKCS11_DEFINE_METHOD(C_DeriveKey, 4);
1623
+ PKCS11_DEFINE_METHOD(C_SeedRandom, 2);
1624
+ PKCS11_DEFINE_METHOD(C_GenerateRandom, 2);
1625
+
1626
+ PKCS11_DEFINE_METHOD(C_WaitForSlotEvent, 1);
1627
+ PKCS11_DEFINE_METHOD(C_Finalize, 0);
1628
+
1629
+ ///////////////////////////////////////
1630
+
1631
+ PKCS11_DEFINE_STRUCT(CK_C_INITIALIZE_ARGS);
1632
+ PKCS11_DEFINE_MEMBER(CK_C_INITIALIZE_ARGS, flags);
1633
+ PKCS11_DEFINE_MEMBER(CK_C_INITIALIZE_ARGS, pReserved);
1634
+
1635
+ cCK_ATTRIBUTE = rb_define_class_under(mPKCS11, "CK_ATTRIBUTE", rb_cObject);
1636
+ rb_define_alloc_func(cCK_ATTRIBUTE, ck_attr_s_alloc);
1637
+ rb_define_method(cCK_ATTRIBUTE, "initialize", ck_attr_initialize, -1);
1638
+ rb_define_method(cCK_ATTRIBUTE, "type", ck_attr_type, 0);
1639
+ rb_define_method(cCK_ATTRIBUTE, "value", ck_attr_value, 0);
1640
+
1641
+ PKCS11_DEFINE_STRUCT(CK_INFO);
1642
+ PKCS11_DEFINE_MEMBER(CK_INFO, cryptokiVersion);
1643
+ PKCS11_DEFINE_MEMBER(CK_INFO, manufacturerID);
1644
+ PKCS11_DEFINE_MEMBER(CK_INFO, flags);
1645
+ PKCS11_DEFINE_MEMBER(CK_INFO, libraryDescription);
1646
+ PKCS11_DEFINE_MEMBER(CK_INFO, libraryVersion);
1647
+
1648
+ PKCS11_DEFINE_STRUCT(CK_SLOT_INFO);
1649
+ PKCS11_DEFINE_MEMBER(CK_SLOT_INFO, slotDescription);
1650
+ PKCS11_DEFINE_MEMBER(CK_SLOT_INFO, manufacturerID);
1651
+ PKCS11_DEFINE_MEMBER(CK_SLOT_INFO, flags);
1652
+ PKCS11_DEFINE_MEMBER(CK_SLOT_INFO, hardwareVersion);
1653
+ PKCS11_DEFINE_MEMBER(CK_SLOT_INFO, firmwareVersion);
1654
+
1655
+ PKCS11_DEFINE_STRUCT(CK_TOKEN_INFO);
1656
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, label);
1657
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, manufacturerID);
1658
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, model);
1659
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, serialNumber);
1660
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, flags);
1661
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulMaxSessionCount);
1662
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulSessionCount);
1663
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulMaxRwSessionCount);
1664
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulRwSessionCount);
1665
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulMaxPinLen);
1666
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulMinPinLen);
1667
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulTotalPublicMemory);
1668
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulFreePublicMemory);
1669
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulTotalPrivateMemory);
1670
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, ulFreePrivateMemory);
1671
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, hardwareVersion);
1672
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, firmwareVersion);
1673
+ PKCS11_DEFINE_MEMBER(CK_TOKEN_INFO, utcTime);
1674
+
1675
+ PKCS11_DEFINE_STRUCT(CK_MECHANISM_INFO);
1676
+ PKCS11_DEFINE_MEMBER(CK_MECHANISM_INFO, ulMinKeySize);
1677
+ PKCS11_DEFINE_MEMBER(CK_MECHANISM_INFO, ulMaxKeySize);
1678
+ PKCS11_DEFINE_MEMBER(CK_MECHANISM_INFO, flags);
1679
+
1680
+ PKCS11_DEFINE_STRUCT(CK_SESSION_INFO);
1681
+ PKCS11_DEFINE_MEMBER(CK_SESSION_INFO, slotID);
1682
+ PKCS11_DEFINE_MEMBER(CK_SESSION_INFO, state);
1683
+ PKCS11_DEFINE_MEMBER(CK_SESSION_INFO, flags);
1684
+ PKCS11_DEFINE_MEMBER(CK_SESSION_INFO, ulDeviceError);
1685
+
1686
+ PKCS11_DEFINE_STRUCT(CK_MECHANISM);
1687
+ rb_define_method(cCK_MECHANISM, "initialize", cCK_MECHANISM_initialize, -1);
1688
+ PKCS11_DEFINE_MEMBER(CK_MECHANISM, mechanism);
1689
+ PKCS11_DEFINE_MEMBER(CK_MECHANISM, pParameter);
1690
+
1691
+ //CK_RSA_PKCS_OAEP_PARAMS
1692
+ //CK_RSA_PKCS_PSS_PARAMS
1693
+ //CK_AES_CBC_ENCRYPT_DATA_PARAMS
1694
+ //CK_AES_CTR_PARAMS
1695
+ //CK_ARIA_CBC_ENCRYPT_DATA_PARAMS
1696
+ //CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS
1697
+ //CK_CAMELLIA_CTR_PARAMS
1698
+ //CK_CMS_SIG_PARAMS
1699
+ //CK_DES_CBC_ENCRYPT_DATA_PARAMS
1700
+ //CK_ECDH1_DERIVE_PARAMS
1701
+ //CK_ECDH2_DERIVE_PARAMS
1702
+ //CK_ECMQV_DERIVE_PARAMS
1703
+ //CK_FUNCTION_LIST
1704
+ //CK_KEA_DERIVE_PARAMS
1705
+ //CK_KEY_DERIVATION_STRING_DATA
1706
+ //CK_KEY_WRAP_SET_OAEP_PARAMS
1707
+ //CK_KIP_PARAMS
1708
+ //CK_OTP_PARAM
1709
+ //CK_OTP_PARAMS
1710
+ //CK_OTP_SIGNATURE_INFO
1711
+ //CK_PBE_PARAMS
1712
+ //CK_PKCS5_PBKD2_PARAMS
1713
+ //CK_RC2_CBC_PARAMS
1714
+ //CK_RC2_MAC_GENERAL_PARAMS
1715
+ //CK_RC5_CBC_PARAMS
1716
+ //CK_RC5_MAC_GENERAL_PARAMS
1717
+ //CK_RC5_PARAMS
1718
+ //CK_SKIPJACK_PRIVATE_WRAP_PARAMS
1719
+ //CK_SKIPJACK_RELAYX_PARAMS
1720
+ //CK_SSL3_KEY_MAT_OUT
1721
+ //CK_SSL3_KEY_MAT_PARAMS
1722
+ //CK_SSL3_MASTER_KEY_DERIVE_PARAMS
1723
+ //CK_SSL3_RANDOM_DATA
1724
+ //CK_TLS_PRF_PARAMS
1725
+ //CK_WTLS_KEY_MAT_OUT
1726
+ //CK_WTLS_KEY_MAT_PARAMS
1727
+ //CK_WTLS_MASTER_KEY_DERIVE_PARAMS
1728
+ //CK_WTLS_PRF_PARAMS
1729
+ //CK_WTLS_RANDOM_DATA
1730
+ //CK_X9_42_DH1_DERIVE_PARAMS
1731
+ //CK_X9_42_DH2_DERIVE_PARAMS
1732
+ //CK_X9_42_MQV_DERIVE_PARAMS
1733
+
1734
+ ///////////////////////////////////////
1735
+
1736
+ Init_pkcs11_const(mPKCS11);
1737
+ }