pkcs11 0.1.0-x86-mingw32 → 0.2.0-x86-mingw32
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/.yardopts +2 -0
- data/History.txt +23 -0
- data/Manifest.txt +6 -0
- data/README.rdoc +28 -15
- data/Rakefile +51 -2
- data/ext/extconf.rb +1 -0
- data/ext/generate_structs.rb +157 -0
- data/ext/generate_thread_funcs.rb +72 -0
- data/ext/pk11.c +482 -252
- data/ext/pk11.h +4 -1
- data/ext/pk11_const.c +25 -476
- data/ext/pk11_const_def.inc +452 -0
- data/ext/pk11_struct_def.inc +304 -0
- data/ext/pk11_struct_impl.inc +304 -0
- data/ext/pk11_thread_funcs.c +411 -0
- data/ext/pk11_thread_funcs.h +482 -0
- data/lib/1.8/pkcs11_ext.so +0 -0
- data/lib/1.9/pkcs11_ext.so +0 -0
- data/lib/pkcs11.rb +5 -8
- data/lib/pkcs11/extensions.rb +17 -109
- data/lib/pkcs11/helper.rb +151 -0
- data/lib/pkcs11/library.rb +44 -13
- data/lib/pkcs11/object.rb +73 -17
- data/lib/pkcs11/session.rb +318 -121
- data/lib/pkcs11/slot.rb +30 -9
- data/test/helper.rb +13 -6
- data/test/test_pkcs11.rb +13 -2
- data/test/test_pkcs11_crypt.rb +38 -3
- data/test/test_pkcs11_object.rb +18 -4
- data/test/test_pkcs11_session.rb +28 -2
- data/test/test_pkcs11_slot.rb +9 -6
- data/test/test_pkcs11_structs.rb +134 -0
- data/test/test_pkcs11_thread.rb +45 -0
- metadata +40 -7
data/.yardopts
ADDED
data/History.txt
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
=== 0.2.0 / 2011-01-18
|
2
|
+
|
3
|
+
* switch API documentation to YARD instead of RDOC
|
4
|
+
* add Ruby classes for all PKCS#11 structures
|
5
|
+
* add CopyObject
|
6
|
+
* add Get/SetOperationState
|
7
|
+
* use distinct Exception classes for different error codes
|
8
|
+
* PKCS#11 function calls don't block other ruby threads any more (only Ruby 1.9, Rubinius)
|
9
|
+
* don't wrap mechanisms any more (GetMechanismList returns plain Integers now)
|
10
|
+
* choose structs as mechanism parameter based on the given mechanism
|
11
|
+
* autogenerate many constants from C header files
|
12
|
+
* finer graded control over library loading
|
13
|
+
* several bug fixes
|
14
|
+
* more unit tests
|
15
|
+
* more documentation
|
16
|
+
|
17
|
+
|
1
18
|
=== 0.1.0 / 2010-05-03
|
2
19
|
|
3
20
|
* first rubygem version
|
21
|
+
* Most functions and operations of PKCS#11 v2.2 are implemented.
|
22
|
+
* The library is based on the work of Ryosuke Kutsuna and GOTOU Yuuzou, but extended in the following ways:
|
23
|
+
- running on Unix and Windows OS
|
24
|
+
- downloadable as rubygem in source and win32 binary version
|
25
|
+
- new API, it's more ruby-like and well documented
|
26
|
+
- most functions are unit tested with help of softokn library
|
data/Manifest.txt
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
.autotest
|
2
|
+
.yardopts
|
2
3
|
History.txt
|
3
4
|
MIT-LICENSE
|
4
5
|
Manifest.txt
|
5
6
|
README.rdoc
|
6
7
|
Rakefile
|
7
8
|
ext/extconf.rb
|
9
|
+
ext/generate_structs.rb
|
10
|
+
ext/generate_thread_funcs.rb
|
8
11
|
ext/include/cryptoki.h
|
9
12
|
ext/include/ct-kip.h
|
10
13
|
ext/include/otp-pkcs11.h
|
@@ -17,6 +20,7 @@ ext/pk11.h
|
|
17
20
|
ext/pk11_const.c
|
18
21
|
lib/pkcs11.rb
|
19
22
|
lib/pkcs11/extensions.rb
|
23
|
+
lib/pkcs11/helper.rb
|
20
24
|
lib/pkcs11/library.rb
|
21
25
|
lib/pkcs11/object.rb
|
22
26
|
lib/pkcs11/session.rb
|
@@ -32,3 +36,5 @@ test/test_pkcs11_crypt.rb
|
|
32
36
|
test/test_pkcs11_object.rb
|
33
37
|
test/test_pkcs11_session.rb
|
34
38
|
test/test_pkcs11_slot.rb
|
39
|
+
test/test_pkcs11_structs.rb
|
40
|
+
test/test_pkcs11_thread.rb
|
data/README.rdoc
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
= PKCS #11/Ruby Interface
|
2
2
|
|
3
3
|
* Homepage: http://github.com/larskanis/pkcs11
|
4
|
-
* older SVN repository: http://coderepos.org/share/log/lang/ruby/pkcs11-ruby
|
5
4
|
* API documentation: http://pkcs11.rubyforge.org/pkcs11/
|
6
5
|
|
7
6
|
This module allows Ruby programs to interface with "RSA Security Inc.
|
@@ -20,12 +19,14 @@ This module works on the Unix like operating systems and win32.
|
|
20
19
|
|
21
20
|
gem install pkcs11
|
22
21
|
|
22
|
+
This installs the PKCS#11 extension either by compiling (Unix) or by using the precompiled gem for Win32.
|
23
23
|
|
24
24
|
== Usage
|
25
25
|
Cryptoki has a reputation to be complicated to implement and use.
|
26
|
-
While this seems to be true for C it
|
26
|
+
While this seems to be true for C it shouldn't for Ruby.
|
27
27
|
|
28
|
-
PKCS11.open
|
28
|
+
{PKCS11.open} opens a PKCS#11 Unix *.so file or Windows-DLL. It requires
|
29
|
+
a suitable PKCS #11 implementation.
|
29
30
|
|
30
31
|
require "rubygems"
|
31
32
|
require "pkcs11"
|
@@ -33,19 +34,23 @@ PKCS11.open requires suitable PKCS #11 implementation as UN*X *.so file or Windo
|
|
33
34
|
|
34
35
|
pkcs11 = PKCS11.open("/path/to/pkcs11.so")
|
35
36
|
p pkcs11.info
|
36
|
-
|
37
|
-
session = slot.open
|
37
|
+
session = pkcs11.active_slots.first.open
|
38
38
|
session.login(:USER, "1234")
|
39
|
-
...
|
39
|
+
# ... crypto operations
|
40
40
|
session.logout
|
41
41
|
session.close
|
42
42
|
|
43
|
-
|
44
|
-
|
43
|
+
This opens a {PKCS11::Session} to the first active slot of the device.
|
44
|
+
A {PKCS11::Session} can be used for all cryptographic operations
|
45
|
+
on the device.
|
45
46
|
|
46
47
|
Detail information for the API specification is provided by RSA Security Inc.
|
47
48
|
Please refer the URL: http://www.rsa.com/rsalabs/node.asp?id=2133.
|
48
49
|
|
50
|
+
Many usage examples can be found in the unit tests of the <tt>test</tt>
|
51
|
+
directory of the project or gem.
|
52
|
+
|
53
|
+
|
49
54
|
|
50
55
|
== Cross compiling for mswin32
|
51
56
|
|
@@ -78,18 +83,18 @@ directory.
|
|
78
83
|
|
79
84
|
== ToDo
|
80
85
|
|
81
|
-
*
|
82
|
-
*
|
83
|
-
*
|
86
|
+
* encoding support for Ruby 1.9
|
87
|
+
* support for proprietary extensions of different vendors
|
88
|
+
* PKCS#11 v2.3
|
84
89
|
|
85
90
|
== Development Status
|
86
91
|
|
87
92
|
STATE FUNCTION NOTE
|
88
93
|
------ --------------------- ----------------------------------------
|
89
|
-
|
90
|
-
DONE C_Finalize
|
94
|
+
DONE C_Initialize
|
95
|
+
DONE C_Finalize
|
91
96
|
DONE C_GetInfo
|
92
|
-
|
97
|
+
DONE C_GetFunctionList
|
93
98
|
DONE C_GetSlotList
|
94
99
|
DONE C_GetSlotInfo
|
95
100
|
DONE C_GetTokenInfo
|
@@ -107,7 +112,7 @@ directory.
|
|
107
112
|
DONE C_Login
|
108
113
|
DONE C_Logout
|
109
114
|
DONE C_CreateObject
|
110
|
-
|
115
|
+
DONE C_CopyObject
|
111
116
|
DONE C_DestroyObject
|
112
117
|
DONE C_GetObjectSize
|
113
118
|
DONE C_GetAttributeValue
|
@@ -154,3 +159,11 @@ directory.
|
|
154
159
|
N/A C_GetFunctionStatus legacy function
|
155
160
|
N/A C_CancelFunction legacy function
|
156
161
|
DONE C_WaitForSlotEvent
|
162
|
+
|
163
|
+
== Authors
|
164
|
+
* Ryosuke Kutsuna <ryosuke@deer-n-horse.jp>
|
165
|
+
* GOTOU Yuuzou <gotoyuzo@notwork.org>
|
166
|
+
* Lars Kanis <kanis@comcard.de>
|
167
|
+
|
168
|
+
== Copying
|
169
|
+
See MIT-LICENSE included in the package.
|
data/Rakefile
CHANGED
@@ -4,19 +4,40 @@
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'hoe'
|
6
6
|
require 'rake/extensiontask'
|
7
|
+
require 'rbconfig'
|
8
|
+
|
9
|
+
CLEAN.include 'ext/pk11_struct_def.inc'
|
10
|
+
CLEAN.include 'ext/pk11_struct_impl.inc'
|
11
|
+
CLEAN.include 'ext/pk11_const_def.inc'
|
12
|
+
CLEAN.include 'ext/pk11_thread_funcs.h'
|
13
|
+
CLEAN.include 'ext/pk11_thread_funcs.c'
|
14
|
+
CLEAN.include 'lib/pkcs11_ext.so'
|
15
|
+
CLEAN.include 'tmp'
|
7
16
|
|
8
17
|
hoe = Hoe.spec 'pkcs11' do
|
9
18
|
developer('Ryosuke Kutsuna', 'ryosuke@deer-n-horse.jp')
|
10
19
|
developer('GOTOU Yuuzou', 'gotoyuzo@notwork.org')
|
11
20
|
developer('Lars Kanis', 'kanis@comcard.de')
|
21
|
+
extra_dev_deps << ['yard', '>= 0.6']
|
22
|
+
extra_dev_deps << ['rake-compiler', '>= 0.7']
|
23
|
+
|
12
24
|
self.url = 'http://github.com/larskanis/pkcs11'
|
13
|
-
|
25
|
+
self.summary = 'PKCS#11 binding for Ruby'
|
26
|
+
self.description = 'This module allows Ruby programs to interface with "RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki)".'
|
27
|
+
|
14
28
|
self.readme_file = 'README.rdoc'
|
15
29
|
self.extra_rdoc_files << self.readme_file << 'ext/pk11.c'
|
16
30
|
spec_extras[:extensions] = 'ext/extconf.rb'
|
31
|
+
spec_extras[:files] = File.read_utf("Manifest.txt").split(/\r?\n\r?/)
|
32
|
+
spec_extras[:files] << 'ext/pk11_struct_impl.inc'
|
33
|
+
spec_extras[:files] << 'ext/pk11_struct_def.inc'
|
34
|
+
spec_extras[:files] << 'ext/pk11_const_def.inc'
|
35
|
+
spec_extras[:files] << 'ext/pk11_thread_funcs.h'
|
36
|
+
spec_extras[:files] << 'ext/pk11_thread_funcs.c'
|
37
|
+
spec_extras[:has_rdoc] = 'yard'
|
17
38
|
end
|
18
39
|
|
19
|
-
ENV['RUBY_CC_VERSION']
|
40
|
+
ENV['RUBY_CC_VERSION'] ||= '1.8.6:1.9.2'
|
20
41
|
|
21
42
|
Rake::ExtensionTask.new('pkcs11_ext', hoe.spec) do |ext|
|
22
43
|
ext.ext_dir = 'ext'
|
@@ -24,6 +45,34 @@ Rake::ExtensionTask.new('pkcs11_ext', hoe.spec) do |ext|
|
|
24
45
|
ext.cross_platform = ['i386-mswin32', 'i386-mingw32'] # forces the Windows platform instead of the default one
|
25
46
|
end
|
26
47
|
|
48
|
+
file 'ext/extconf.rb' => ['ext/pk11_struct_def.inc', 'ext/pk11_thread_funcs.c']
|
49
|
+
file 'ext/pk11_struct_def.inc' => 'ext/generate_structs.rb' do
|
50
|
+
sh "#{Config::CONFIG['ruby_install_name']} ext/generate_structs.rb --def ext/pk11_struct_def.inc --impl ext/pk11_struct_impl.inc --const ext/pk11_const_def.inc --doc ext/pk11_struct.doc ext/include/pkcs11t.h"
|
51
|
+
end
|
52
|
+
file 'ext/pk11_struct_impl.inc' => 'ext/pk11_struct_def.inc'
|
53
|
+
file 'ext/pk11.c' => 'ext/pk11_struct_def.inc'
|
54
|
+
file 'ext/pk11_const.c' => 'ext/pk11_struct_def.inc'
|
55
|
+
|
56
|
+
file 'ext/pk11_thread_funcs.h' => 'ext/generate_thread_funcs.rb' do
|
57
|
+
sh "#{Config::CONFIG['ruby_install_name']} ext/generate_thread_funcs.rb --impl ext/pk11_thread_funcs.c --decl ext/pk11_thread_funcs.h ext/include/pkcs11f.h"
|
58
|
+
end
|
59
|
+
file 'ext/pk11_thread_funcs.c' => 'ext/pk11_thread_funcs.h'
|
60
|
+
file 'ext/pk11.h' => 'ext/pk11_thread_funcs.h'
|
61
|
+
|
62
|
+
desc "Generate static HTML documentation with YARD"
|
63
|
+
task :yardoc do
|
64
|
+
sh "yardoc"
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "Publish YARD to wherever you want."
|
68
|
+
task :publish_yard => [:yardoc] do
|
69
|
+
rdoc_locations = hoe.rdoc_locations
|
70
|
+
warn "no rdoc_location values" if rdoc_locations.empty?
|
71
|
+
rdoc_locations.each do |dest|
|
72
|
+
sh %{rsync -av --delete doc/ #{dest}}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
27
76
|
# RDoc-upload task for github (currently on rubyforge)
|
28
77
|
#
|
29
78
|
# require 'grancher/task'
|
data/ext/extconf.rb
CHANGED
@@ -0,0 +1,157 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Quick and dirty parser for PKCS#11 structs and
|
3
|
+
# generator for Ruby wrapper classes.
|
4
|
+
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
options = Struct.new(:verbose, :def, :impl, :const, :doc).new
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: #{$0} [options] <header-file.h>*"
|
10
|
+
|
11
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely", &options.method(:verbose=))
|
12
|
+
opts.on("--def FILE", "Write struct definitions to this file", &options.method(:def=))
|
13
|
+
opts.on("--impl FILE", "Write struct implementations to this file", &options.method(:impl=))
|
14
|
+
opts.on("--const FILE", "Write const implementations to this file", &options.method(:const=))
|
15
|
+
opts.on("--doc FILE", "Write documentation to this file", &options.method(:doc=))
|
16
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
17
|
+
puts opts
|
18
|
+
exit
|
19
|
+
end
|
20
|
+
end.parse!
|
21
|
+
|
22
|
+
Attribute = Struct.new(:type, :name, :qual)
|
23
|
+
IgnoreStructs = %w[CK_ATTRIBUTE CK_MECHANISM]
|
24
|
+
OnlyAllocatorStructs = %w[CK_MECHANISM_INFO CK_C_INITIALIZE_ARGS CK_INFO CK_SLOT_INFO CK_TOKEN_INFO CK_SESSION_INFO]
|
25
|
+
|
26
|
+
structs = {}
|
27
|
+
File.open(options.def, "w") do |fd_def|
|
28
|
+
File.open(options.impl, "w") do |fd_impl|
|
29
|
+
File.open(options.doc, "w") do |fd_doc|
|
30
|
+
ARGV.each do |file_h|
|
31
|
+
c_src = IO.read(file_h)
|
32
|
+
c_src.scan(/struct\s+([A-Z_0-9]+)\s*\{(.*?)\}/m) do |struct|
|
33
|
+
struct_name, struct_text = $1, $2
|
34
|
+
|
35
|
+
attrs = {}
|
36
|
+
struct_text.scan(/^\s+([A-Z_0-9]+)\s+([\w_]+)\s*(\[\s*(\d+)\s*\])?/) do |elem|
|
37
|
+
attr = Attribute.new($1, $2, $4)
|
38
|
+
attrs[$1+" "+$2] = attr
|
39
|
+
# puts attr.inspect
|
40
|
+
end
|
41
|
+
structs[struct_name] = attrs
|
42
|
+
|
43
|
+
next if IgnoreStructs.include?(struct_name)
|
44
|
+
|
45
|
+
if OnlyAllocatorStructs.include?(struct_name)
|
46
|
+
fd_impl.puts "PKCS11_IMPLEMENT_ALLOCATOR(#{struct_name});"
|
47
|
+
else
|
48
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRUCT_WITH_ALLOCATOR(#{struct_name});"
|
49
|
+
end
|
50
|
+
fd_def.puts "PKCS11_DEFINE_STRUCT(#{struct_name});"
|
51
|
+
fd_doc.puts"class PKCS11::#{struct_name} < PKCS11::CStruct"
|
52
|
+
fd_doc.puts"# Size of corresponding C struct in bytes\nSIZEOF_STRUCT=Integer"
|
53
|
+
fd_doc.puts"# @return [String] Binary copy of the C struct\ndef to_s; end"
|
54
|
+
fd_doc.puts"# @return [Array<String>] Attributes of this struct\ndef members; end"
|
55
|
+
|
56
|
+
# try to find attributes belonging together
|
57
|
+
attrs.select{|key, attr| ['CK_BYTE_PTR', 'CK_VOID_PTR', 'CK_UTF8CHAR_PTR'].include?(attr.type) }.each do |key, attr|
|
58
|
+
if len_attr=attrs["CK_ULONG #{attr.name.gsub(/^p/, "ul")}Len"]
|
59
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRING_PTR_LEN_ACCESSOR(#{struct_name}, #{attr.name}, #{len_attr.name});"
|
60
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
61
|
+
fd_doc.puts"# @return [String, nil] accessor for #{attr.name} and #{len_attr.name}\nattr_accessor :#{attr.name}"
|
62
|
+
attrs.delete_if{|k,v| v==len_attr}
|
63
|
+
elsif attr.name=='pData' && (len_attr = attrs["CK_ULONG length"] || attrs["CK_ULONG ulLen"])
|
64
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRING_PTR_LEN_ACCESSOR(#{struct_name}, #{attr.name}, #{len_attr.name});"
|
65
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
66
|
+
fd_doc.puts"# @return [String, nil] accessor for #{attr.name} and #{len_attr.name}\nattr_accessor :#{attr.name}"
|
67
|
+
attrs.delete_if{|k,v| v==len_attr}
|
68
|
+
else
|
69
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRING_PTR_ACCESSOR(#{struct_name}, #{attr.name});"
|
70
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
71
|
+
fd_doc.puts"# @return [String, nil] accessor for #{attr.name}\nattr_accessor :#{attr.name}"
|
72
|
+
end
|
73
|
+
attrs.delete_if{|k,v| v==attr}
|
74
|
+
end
|
75
|
+
|
76
|
+
# standalone attributes
|
77
|
+
attrs.each do |key, attr|
|
78
|
+
if attr.qual
|
79
|
+
# Attributes with qualifier
|
80
|
+
case attr.type
|
81
|
+
when 'CK_BYTE', 'CK_UTF8CHAR', 'CK_CHAR'
|
82
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRING_ACCESSOR(#{struct_name}, #{attr.name});"
|
83
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
84
|
+
fd_doc.puts"# @return [String] accessor for #{attr.name} (max #{attr.qual} bytes)\nattr_accessor :#{attr.name}"
|
85
|
+
else
|
86
|
+
fd_impl.puts "/* unimplemented attr #{attr.type} #{attr.name} #{attr.qual} */"
|
87
|
+
fd_def.puts "/* unimplemented attr #{attr.type} #{attr.name} #{attr.qual} */"
|
88
|
+
end
|
89
|
+
else
|
90
|
+
case attr.type
|
91
|
+
when 'CK_BYTE'
|
92
|
+
fd_impl.puts "PKCS11_IMPLEMENT_BYTE_ACCESSOR(#{struct_name}, #{attr.name});"
|
93
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
94
|
+
fd_doc.puts"# @return [Integer] accessor for #{attr.name} (CK_BYTE)\nattr_accessor :#{attr.name}"
|
95
|
+
when 'CK_ULONG', 'CK_FLAGS', 'CK_SLOT_ID', 'CK_STATE', /CK_[A-Z_0-9]+_TYPE/
|
96
|
+
fd_impl.puts "PKCS11_IMPLEMENT_ULONG_ACCESSOR(#{struct_name}, #{attr.name});"
|
97
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
98
|
+
fd_doc.puts"# @return [Integer] accessor for #{attr.name} (CK_ULONG)\nattr_accessor :#{attr.name}"
|
99
|
+
when 'CK_OBJECT_HANDLE'
|
100
|
+
fd_impl.puts "PKCS11_IMPLEMENT_HANDLE_ACCESSOR(#{struct_name}, #{attr.name});"
|
101
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
102
|
+
fd_doc.puts"# @return [Integer, PKCS11::Object] Object handle (CK_ULONG)\nattr_accessor :#{attr.name}"
|
103
|
+
when 'CK_BBOOL'
|
104
|
+
fd_impl.puts "PKCS11_IMPLEMENT_BOOL_ACCESSOR(#{struct_name}, #{attr.name});"
|
105
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
106
|
+
fd_doc.puts"# @return [Boolean] Bool value\nattr_accessor :#{attr.name}"
|
107
|
+
when 'CK_ULONG_PTR'
|
108
|
+
fd_impl.puts "PKCS11_IMPLEMENT_ULONG_PTR_ACCESSOR(#{struct_name}, #{attr.name});"
|
109
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
110
|
+
fd_doc.puts"# @return [Integer, nil] accessor for #{attr.name} (CK_ULONG_PTR)\nattr_accessor :#{attr.name}"
|
111
|
+
else
|
112
|
+
# Struct attributes
|
113
|
+
if structs[attr.type]
|
114
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRUCT_ACCESSOR(#{struct_name}, #{attr.type}, #{attr.name});"
|
115
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
116
|
+
fd_doc.puts"# @return [PKCS11::#{attr.type}] inline struct\nattr_accessor :#{attr.name}"
|
117
|
+
elsif structs[attr.type.gsub(/_PTR$/,'')]
|
118
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRUCT_PTR_ACCESSOR(#{struct_name}, #{attr.type.gsub(/_PTR$/,'')}, #{attr.name});"
|
119
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct_name}, #{attr.name});"
|
120
|
+
fd_doc.puts"# @return [PKCS11::#{attr.type.gsub(/_PTR$/,'')}, nil] pointer to struct\nattr_accessor :#{attr.name}"
|
121
|
+
else
|
122
|
+
fd_impl.puts "/* unimplemented attr #{attr.type} #{attr.name} #{attr.qual} */"
|
123
|
+
fd_def.puts "/* unimplemented attr #{attr.type} #{attr.name} #{attr.qual} */"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
fd_impl.puts
|
130
|
+
fd_def.puts
|
131
|
+
fd_doc.puts"end"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
ConstTemplate = Struct.new :regexp, :def
|
139
|
+
ConstGroups = [
|
140
|
+
ConstTemplate.new(/#define\s+(CKM_[A-Z_0-9]+)\s+(\w+)/, 'PKCS11_DEFINE_MECHANISM'),
|
141
|
+
ConstTemplate.new(/#define\s+(CKA_[A-Z_0-9]+)\s+(\w+)/, 'PKCS11_DEFINE_ATTRIBUTE'),
|
142
|
+
ConstTemplate.new(/#define\s+(CKO_[A-Z_0-9]+)\s+(\w+)/, 'PKCS11_DEFINE_OBJECT_CLASS'),
|
143
|
+
ConstTemplate.new(/#define\s+(CKR_[A-Z_0-9]+)\s+(\w+)/, 'PKCS11_DEFINE_RETURN_VALUE'),
|
144
|
+
]
|
145
|
+
|
146
|
+
File.open(options.const, "w") do |fd_const|
|
147
|
+
ARGV.each do |file_h|
|
148
|
+
c_src = IO.read(file_h)
|
149
|
+
ConstGroups.each do |const_group|
|
150
|
+
c_src.scan(const_group.regexp) do
|
151
|
+
const_name, const_value = $1, $2
|
152
|
+
|
153
|
+
fd_const.puts "#{const_group.def}(#{const_name}); /* #{const_value} */"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This quick and dirty parser for PKCS#11 functions generates
|
3
|
+
# wrapper functions for using rb_thread_blocking_region()
|
4
|
+
# of Ruby 1.9.
|
5
|
+
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
options = Struct.new(:verbose, :impl, :decl).new
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
opts.banner = "Usage: #{$0} [options] <header-file.h>*"
|
11
|
+
|
12
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely", &options.method(:verbose=))
|
13
|
+
opts.on("--decl FILE", "Write declarations to this file", &options.method(:decl=))
|
14
|
+
opts.on("--impl FILE", "Write implementations to this file", &options.method(:impl=))
|
15
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
16
|
+
puts opts
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
end.parse!
|
20
|
+
|
21
|
+
Attribute = Struct.new(:type, :name)
|
22
|
+
|
23
|
+
File.open(options.decl, "w") do |fd_decl|
|
24
|
+
File.open(options.impl, "w") do |fd_impl|
|
25
|
+
fd_decl.puts <<-EOT
|
26
|
+
#ifndef #{options.decl.gsub(/[^\w]/, "_").upcase}
|
27
|
+
#define #{options.decl.gsub(/[^\w]/, "_").upcase}
|
28
|
+
#include "pk11.h"
|
29
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
30
|
+
EOT
|
31
|
+
fd_impl.puts <<-EOT
|
32
|
+
#include #{File.basename(options.decl).inspect}
|
33
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
34
|
+
EOT
|
35
|
+
ARGV.each do |file_h|
|
36
|
+
c_src = IO.read(file_h)
|
37
|
+
c_src.scan(/CK_PKCS11_FUNCTION_INFO\((.+?)\).*?\((.*?)\);/m) do
|
38
|
+
func_name, func_param_list = $1, $2
|
39
|
+
func_params = []
|
40
|
+
func_param_list.scan(/^\s+([A-Z_0-9]+)\s+([\w_]+)/) do |elem|
|
41
|
+
func_params << Attribute.new($1, $2)
|
42
|
+
end
|
43
|
+
puts "func_name:#{func_name.inspect} func_params: #{func_params.inspect}" if options.verbose
|
44
|
+
|
45
|
+
fd_decl.puts <<-EOT
|
46
|
+
struct tbr_#{func_name}_params {
|
47
|
+
CK_#{func_name} func;
|
48
|
+
struct { #{ func_params.map{|f| f.type+" "+f.name+";"}.join } } params;
|
49
|
+
CK_RV retval;
|
50
|
+
};
|
51
|
+
VALUE tbf_#{func_name}( void *data );
|
52
|
+
|
53
|
+
EOT
|
54
|
+
fd_impl.puts <<-EOT
|
55
|
+
VALUE tbf_#{func_name}( void *data ){
|
56
|
+
struct tbr_#{func_name}_params *p = (struct tbr_#{func_name}_params*)data;
|
57
|
+
p->retval = p->func( #{func_params.map{|f| "p->params."+f.name}.join(",") } );
|
58
|
+
return Qnil;
|
59
|
+
}
|
60
|
+
|
61
|
+
EOT
|
62
|
+
end
|
63
|
+
end
|
64
|
+
fd_impl.puts <<-EOT
|
65
|
+
#endif
|
66
|
+
EOT
|
67
|
+
fd_decl.puts <<-EOT
|
68
|
+
#endif
|
69
|
+
#endif
|
70
|
+
EOT
|
71
|
+
end
|
72
|
+
end
|