pkcs11_luna 0.3.1 → 0.3.2
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Manifest.txt +11 -11
- data/Rakefile +25 -26
- data/ext/extconf.rb +12 -0
- data/ext/generate_constants.rb +38 -38
- data/ext/generate_luna_constants.rb +57 -0
- data/ext/generate_luna_structs.rb +76 -0
- data/ext/generate_structs.rb +183 -43
- data/ext/pk11_version.h +1 -1
- data/ext/std_structs.rb +1 -0
- metadata +7 -8
- metadata.gz.sig +0 -0
- data/ext/pk11l_const_def.inc +0 -804
- data/ext/pk11l_struct.doc +0 -1012
- data/ext/pk11l_struct_def.inc +0 -388
- data/ext/pk11l_struct_impl.inc +0 -388
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ab768035f9878757fd9c12ff2a34e35796800830da20742347d22cb14bde0fb
|
4
|
+
data.tar.gz: 87e8780aa05abcc0a4090fc82e3d8070d041cc34cfb44a6b63988cebc07b4a22
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e35a4208dddfab2d701895744291dab50219956af681d283bca92d538d880a1af965dde05fd8eaf742a504c2790f1b0be15a6ab7658d1963cd273331f487dee
|
7
|
+
data.tar.gz: dab50ef8b7edd8d5b330057d3a8c0470c94cb8e8e45450c4a2da0e5f50f496acf556ee778c84400d7965c1964259c8bd9ae1d624b0d1f98548e7eaddd19d9fb5
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Manifest.txt
CHANGED
@@ -3,22 +3,22 @@
|
|
3
3
|
Manifest.txt
|
4
4
|
README_LUNA.rdoc
|
5
5
|
Rakefile
|
6
|
-
ext/extconf.rb
|
7
|
-
ext/generate_constants.rb
|
8
|
-
ext/generate_structs.rb
|
9
|
-
ext/pk11l.c
|
10
|
-
lib/pkcs11_luna.rb
|
11
|
-
lib/pkcs11_luna/extensions.rb
|
12
|
-
test/luna_helper.rb
|
13
|
-
test/app_id_helper.rb
|
14
|
-
test/test_pkcs11_luna.rb
|
15
|
-
test/test_pkcs11_luna_crypt.rb
|
16
6
|
examples/config.rb
|
17
7
|
examples/derive_aes_ecdh_key.rb
|
18
|
-
examples/sign_verify.rb
|
19
8
|
examples/encrypt_decrypt_aes.rb
|
20
9
|
examples/encrypt_decrypt_rsa.rb
|
21
10
|
examples/mechanism_list.rb
|
22
11
|
examples/multithread.rb
|
23
12
|
examples/objects_list.rb
|
13
|
+
examples/sign_verify.rb
|
24
14
|
examples/slot_info.rb
|
15
|
+
ext/extconf.rb
|
16
|
+
ext/generate_luna_constants.rb
|
17
|
+
ext/generate_luna_structs.rb
|
18
|
+
ext/pk11l.c
|
19
|
+
lib/pkcs11_luna.rb
|
20
|
+
lib/pkcs11_luna/extensions.rb
|
21
|
+
test/app_id_helper.rb
|
22
|
+
test/luna_helper.rb
|
23
|
+
test/test_pkcs11_luna.rb
|
24
|
+
test/test_pkcs11_luna_crypt.rb
|
data/Rakefile
CHANGED
@@ -7,30 +7,38 @@ require 'rake/extensiontask'
|
|
7
7
|
require 'rbconfig'
|
8
8
|
|
9
9
|
LUNA_INCLUDE_DIR = ENV['LUNA_INCLUDE_DIR'] || '/usr/safenet/lunaclient/samples/include'
|
10
|
-
|
10
|
+
RUBY_PKCS11_DIR = File.expand_path('..')
|
11
|
+
$: << File.join(RUBY_PKCS11_DIR, "lib")
|
11
12
|
|
12
|
-
|
13
|
-
GENERATED_FILES = [
|
14
|
-
'ext/pk11l_struct_impl.inc',
|
15
|
-
'ext/pk11l_struct_def.inc',
|
16
|
-
'ext/pk11l_const_def.inc',
|
17
|
-
'ext/pk11l_struct.doc',
|
13
|
+
SHARED_FILES = [
|
18
14
|
'ext/pk11_struct_macros.h',
|
19
15
|
'ext/pk11_const_macros.h',
|
20
16
|
'ext/pk11_version.h',
|
17
|
+
'ext/generate_structs.rb',
|
18
|
+
'ext/generate_constants.rb',
|
19
|
+
]
|
20
|
+
GENERATED_FILES = [
|
21
|
+
"ext/std_structs.rb"
|
21
22
|
]
|
22
23
|
|
24
|
+
CLEAN.include SHARED_FILES
|
23
25
|
CLEAN.include GENERATED_FILES
|
24
26
|
CLEAN.include 'lib/pkcs11_luna_ext.so'
|
25
27
|
CLEAN.include 'tmp'
|
26
28
|
CLEAN.include 'examples/output'
|
27
29
|
|
28
30
|
def pkcs11_version
|
29
|
-
file = File.join(
|
31
|
+
file = File.join(RUBY_PKCS11_DIR, 'ext/pk11_version.h')
|
30
32
|
version_re = /VERSION += +([\"\'])([\d][\d\w\.]+)\1/
|
31
33
|
File.read_utf(file)[version_re, 2]
|
32
34
|
end
|
33
35
|
|
36
|
+
# Ensure pkg is rebuilt
|
37
|
+
task :remove_pkg do
|
38
|
+
rm_rf 'pkg'
|
39
|
+
end
|
40
|
+
task :gem => [:remove_pkg]
|
41
|
+
|
34
42
|
hoe = Hoe.spec 'pkcs11_luna' do
|
35
43
|
developer('SafeNet', 'support@safenet-inc.com')
|
36
44
|
extra_deps << ['pkcs11', "= #{pkcs11_version}"]
|
@@ -46,7 +54,7 @@ hoe = Hoe.spec 'pkcs11_luna' do
|
|
46
54
|
self.extra_rdoc_files << self.readme_file << 'ext/pk11l.c'
|
47
55
|
spec_extras[:extensions] = 'ext/extconf.rb'
|
48
56
|
spec_extras[:files] = File.read_utf("Manifest.txt").split(/\r?\n\r?/)
|
49
|
-
spec_extras[:files] += GENERATED_FILES
|
57
|
+
spec_extras[:files] += SHARED_FILES + GENERATED_FILES
|
50
58
|
spec_extras[:required_ruby_version] = '>= 2.2.0'
|
51
59
|
end
|
52
60
|
|
@@ -58,29 +66,20 @@ Rake::ExtensionTask.new('pkcs11_luna_ext', hoe.spec) do |ext|
|
|
58
66
|
ext.config_options << "--with-luna-dir-include=\"#{LUNA_INCLUDE_DIR}\""
|
59
67
|
end
|
60
68
|
|
61
|
-
|
62
|
-
|
69
|
+
# Add shared file from base pkcs11 gem
|
70
|
+
SHARED_FILES.each do |filename|
|
71
|
+
file filename => File.join(RUBY_PKCS11_DIR, filename) do |t|
|
63
72
|
cp t.prerequisites.first, t.name, verbose: true
|
64
73
|
end
|
74
|
+
file 'ext/extconf.rb' => filename
|
65
75
|
end
|
66
76
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
HEADER_FILES = "#{LUNA_INCLUDE_DIR}/RSA/pkcs11t.h #{LUNA_INCLUDE_DIR}/cryptoki_v2.h"
|
72
|
-
|
73
|
-
file 'ext/extconf.rb' => ['ext/pk11l_struct_def.inc', 'ext/pk11l_const_def.inc', 'ext/pk11_struct_macros.h', 'ext/pk11_const_macros.h', 'ext/pk11_version.h']
|
74
|
-
file 'ext/pk11l_struct_def.inc' => 'ext/generate_structs.rb' do
|
75
|
-
sh "#{RbConfig::CONFIG['ruby_install_name']} -I../lib ext/generate_structs.rb --def ext/pk11l_struct_def.inc --impl ext/pk11l_struct_impl.inc --doc ext/pk11l_struct.doc #{HEADER_FILES}"
|
76
|
-
end
|
77
|
-
file 'ext/pk11l_struct_impl.inc' => 'ext/pk11l_struct_def.inc'
|
78
|
-
file 'ext/pk11l_struct.doc' => 'ext/pk11l_struct_def.inc'
|
77
|
+
file "ext/std_structs.rb" do |t|
|
78
|
+
require "pkcs11"
|
79
|
+
std_structs = PKCS11.constants.select{|c| PKCS11.const_get(c).respond_to?(:ancestors) && !(PKCS11.const_get(c).ancestors & [PKCS11::CStruct, PKCS11::CK_ATTRIBUTE]).empty? }
|
79
80
|
|
80
|
-
|
81
|
-
sh "#{RbConfig::CONFIG['ruby_install_name']} -I../lib ext/generate_constants.rb --const ext/pk11l_const_def.inc #{HEADER_FILES}"
|
81
|
+
File.write t.name, "PKCS11_STD_STRUCTS = #{std_structs.inspect}"
|
82
82
|
end
|
83
|
-
file 'ext/pk11l.c' => ['ext/pk11l_struct_def.inc', 'ext/pk11l_struct_impl.inc', 'ext/pk11l_const_def.inc']
|
84
83
|
|
85
84
|
task doc_files: 'ext/pk11l_struct.doc'
|
86
85
|
|
data/ext/extconf.rb
CHANGED
@@ -4,6 +4,18 @@ require "rubygems"
|
|
4
4
|
inc, lib = dir_config('luna-dir', '/usr/safenet/lunaclient/samples')
|
5
5
|
puts "using Luna Client include:#{inc}"
|
6
6
|
|
7
|
+
require_relative "generate_luna_constants"
|
8
|
+
require_relative "generate_luna_structs"
|
9
|
+
|
10
|
+
header_files = [File.join(inc, "RSA/pkcs11t.h"), File.join(inc, "cryptoki_v2.h")]
|
11
|
+
|
12
|
+
args = ["--const", "pk11l_const_def.inc", *header_files]
|
13
|
+
puts "running const parser with: #{args.join(" ")}"
|
14
|
+
PKCS11::Luna::ConstantParser.run(args)
|
15
|
+
|
16
|
+
args = ["--def", "pk11l_struct_def.inc", "--impl", "pk11l_struct_impl.inc", "--doc", "pk11l_struct.doc", *header_files]
|
17
|
+
puts "running struct parser with: #{args.join(" ")}"
|
18
|
+
PKCS11::Luna::StructParser.run(args)
|
7
19
|
|
8
20
|
find_header('pk11_struct_macros.h')
|
9
21
|
find_header('pk11_const_macros.h')
|
data/ext/generate_constants.rb
CHANGED
@@ -2,56 +2,56 @@
|
|
2
2
|
# Quick and dirty parser for PKCS#11 constants and
|
3
3
|
# generator for Ruby wrapper classes.
|
4
4
|
|
5
|
-
require
|
5
|
+
require 'optparse'
|
6
6
|
|
7
7
|
module PKCS11
|
8
|
-
|
9
|
-
|
8
|
+
class ConstantParser
|
9
|
+
|
10
|
+
attr_accessor :options
|
11
|
+
|
12
|
+
def self.run(argv)
|
13
|
+
s = self.new
|
14
|
+
options = Struct.new(:verbose, :const, :files).new
|
15
|
+
OptionParser.new do |opts|
|
16
|
+
opts.banner = "Usage: #{$0} [options] <header-file.h>*"
|
17
|
+
|
18
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely", &options.method(:verbose=))
|
19
|
+
opts.on("--const FILE", "Write const implementations to this file", &options.method(:const=))
|
20
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
21
|
+
puts opts
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
end.parse!(argv)
|
25
|
+
options.files = argv
|
26
|
+
s.options = options
|
27
|
+
s.start!
|
28
|
+
end
|
29
|
+
|
30
|
+
ConstTemplate = Struct.new :regexp, :def
|
10
31
|
ConstGroups = [
|
11
|
-
ConstTemplate.new(/#define\s+(CKM_[A-Z_0-9]+)\s+(
|
12
|
-
ConstTemplate.new(/#define\s+(CKA_[A-Z_0-9]+)\s+(
|
13
|
-
ConstTemplate.new(/#define\s+(CKO_[A-Z_0-9]+)\s+(
|
14
|
-
ConstTemplate.new(/#define\s+(CKR_[A-Z_0-9]+)\s+(
|
32
|
+
ConstTemplate.new(/#define\s+(CKM_[A-Z_0-9]+)\s+(\w+)/, 'PKCS11_DEFINE_MECHANISM'),
|
33
|
+
ConstTemplate.new(/#define\s+(CKA_[A-Z_0-9]+)\s+(\w+)/, 'PKCS11_DEFINE_ATTRIBUTE'),
|
34
|
+
ConstTemplate.new(/#define\s+(CKO_[A-Z_0-9]+)\s+(\w+)/, 'PKCS11_DEFINE_OBJECT_CLASS'),
|
35
|
+
ConstTemplate.new(/#define\s+(CKR_[A-Z_0-9]+)\s+(\w+)/, 'PKCS11_DEFINE_RETURN_VALUE'),
|
15
36
|
]
|
16
|
-
|
17
|
-
['CKD', 'CKU', 'CKF', 'CKDHP', 'CKES', 'CKMS', 'CAF', 'CKCAO', 'CKHSC'].each do |prefix|
|
18
|
-
ConstGroups << ConstTemplate.new(/#define\s+(#{prefix}_[A-Z_0-9]+)\s+([A-Za-z0-9_]+)/, 'PKCS11_DEFINE_CONST')
|
19
|
-
end
|
20
37
|
|
21
|
-
IgnoreConstants = %w[]
|
22
|
-
|
23
38
|
def start!
|
24
|
-
|
25
|
-
constants_hash = {}
|
26
|
-
constants = []
|
27
|
-
|
28
|
-
options.files.each do |file_h|
|
29
|
-
c_src = IO.read(file_h)
|
30
|
-
ConstGroups.each do |const_group|
|
31
|
-
c_src.scan(const_group.regexp) do
|
32
|
-
const_name, const_value = $1, $2
|
33
|
-
next if IgnoreConstants.include?(const_name)
|
34
|
-
constants_hash[const_name] = [const_group.def, const_value]
|
35
|
-
constants.push(const_name)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
39
|
File.open(options.const, "w") do |fd_const|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
40
|
+
options.files.each do |file_h|
|
41
|
+
c_src = IO.read(file_h)
|
42
|
+
ConstGroups.each do |const_group|
|
43
|
+
c_src.scan(const_group.regexp) do
|
44
|
+
const_name, const_value = $1, $2
|
45
|
+
|
46
|
+
fd_const.puts "#{const_group.def}(#{const_name}); /* #{const_value} */"
|
47
|
+
end
|
48
|
+
end
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
50
52
|
end
|
51
|
-
|
52
|
-
end
|
53
53
|
end
|
54
54
|
|
55
55
|
if $0==__FILE__
|
56
|
-
PKCS11::
|
56
|
+
PKCS11::ConstantParser.run(ARGV)
|
57
57
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Quick and dirty parser for PKCS#11 constants and
|
3
|
+
# generator for Ruby wrapper classes.
|
4
|
+
|
5
|
+
require_relative "generate_constants"
|
6
|
+
|
7
|
+
module PKCS11
|
8
|
+
module Luna
|
9
|
+
class ConstantParser < PKCS11::ConstantParser
|
10
|
+
ConstGroups = [
|
11
|
+
ConstTemplate.new(/#define\s+(CKM_[A-Z_0-9]+)\s+(.+)/, 'PKCS11_DEFINE_MECHANISM'),
|
12
|
+
ConstTemplate.new(/#define\s+(CKA_[A-Z_0-9]+)\s+(.+)/, 'PKCS11_DEFINE_ATTRIBUTE'),
|
13
|
+
ConstTemplate.new(/#define\s+(CKO_[A-Z_0-9]+)\s+(.+)/, 'PKCS11_DEFINE_OBJECT_CLASS'),
|
14
|
+
ConstTemplate.new(/#define\s+(CKR_[A-Z_0-9]+)\s+([A-Za-z0-9_\(\)+ ]+)/, 'PKCS11_DEFINE_RETURN_VALUE'),
|
15
|
+
]
|
16
|
+
|
17
|
+
['CKD', 'CKU', 'CKF', 'CKDHP', 'CKES', 'CKMS', 'CAF', 'CKCAO', 'CKHSC'].each do |prefix|
|
18
|
+
ConstGroups << ConstTemplate.new(/#define\s+(#{prefix}_[A-Z_0-9]+)\s+([A-Za-z0-9_]+)/, 'PKCS11_DEFINE_CONST')
|
19
|
+
end
|
20
|
+
|
21
|
+
IgnoreConstants = %w[]
|
22
|
+
|
23
|
+
def start!
|
24
|
+
|
25
|
+
constants_hash = {}
|
26
|
+
constants = []
|
27
|
+
|
28
|
+
options.files.each do |file_h|
|
29
|
+
c_src = File.binread(file_h)
|
30
|
+
ConstGroups.each do |const_group|
|
31
|
+
c_src.scan(const_group.regexp) do
|
32
|
+
const_name, const_value = $1, $2
|
33
|
+
next if IgnoreConstants.include?(const_name)
|
34
|
+
constants_hash[const_name] = [const_group.def, const_value]
|
35
|
+
constants.push(const_name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
File.open(options.const, "w") do |fd_const|
|
41
|
+
constants.each do |const_name|
|
42
|
+
next if constants_hash[const_name].nil?
|
43
|
+
const_group_def = constants_hash[const_name][0]
|
44
|
+
const_value = constants_hash[const_name][1]
|
45
|
+
fd_const.puts "#{const_group_def}(#{const_name}); // #{const_value} "
|
46
|
+
constants_hash[const_name] = nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if $0==__FILE__
|
56
|
+
PKCS11::Luna::ConstantParser.run(ARGV)
|
57
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Quick and dirty parser for PKCS#11 structs and
|
3
|
+
# generator for Ruby wrapper classes.
|
4
|
+
|
5
|
+
require_relative "generate_structs"
|
6
|
+
require_relative "std_structs"
|
7
|
+
|
8
|
+
module PKCS11
|
9
|
+
module Luna
|
10
|
+
class StructParser < PKCS11::StructParser
|
11
|
+
|
12
|
+
SIZE_CONSTANTS = {
|
13
|
+
'CK_MANUFACTURER_SIZE' => 32,
|
14
|
+
'CK_SERIAL_NUMBER_SIZE' => 16,
|
15
|
+
'CK_TIME_SIZE' => 16,
|
16
|
+
'CK_LIB_DESC_SIZE' => 32,
|
17
|
+
'CK_SLOT_DESCRIPTION_SIZE' => 64,
|
18
|
+
'CK_SLOT_MANUFACTURER_SIZE' => 32,
|
19
|
+
'CK_MAX_PIN_LEN' => 32,
|
20
|
+
'CK_TOKEN_LABEL_SIZE' => 32,
|
21
|
+
'CK_TOKEN_MANUFACTURER_SIZE' => 32,
|
22
|
+
'CK_TOKEN_MODEL_SIZE' => 16,
|
23
|
+
'CK_TOKEN_SERIAL_NUMBER_SIZE' => 16,
|
24
|
+
'CK_TOKEN_TIME_SIZE' => 16,
|
25
|
+
'CK_MAX_PBE_IV_SIZE' => 8,
|
26
|
+
'CK_MAX_PAD_SIZE' => 16,
|
27
|
+
'CK_HA_MAX_MEMBERS' => 32
|
28
|
+
}
|
29
|
+
|
30
|
+
ULONG_TYPES = %w[CK_EC_DH_PRIMITIVE CK_EC_ENC_SCHEME CK_EC_MAC_SCHEME CK_KDF_PRF_ENCODING_SCHEME CK_RV]
|
31
|
+
ULONG_PTR_TYPES = %w[]
|
32
|
+
|
33
|
+
|
34
|
+
def struct_module
|
35
|
+
'PKCS11::Luna'
|
36
|
+
end
|
37
|
+
|
38
|
+
def array_attribute_names; %w[attributes mechanism certAttr hCert]; end
|
39
|
+
|
40
|
+
def parse_files(files)
|
41
|
+
structs = []
|
42
|
+
files.each do |file_h|
|
43
|
+
c_src = File.binread(file_h)
|
44
|
+
c_src.scan(/struct\s+([A-Z_0-9]+)\s*\{(.*?)\}\s*([A-Z_0-9]+)\s*;/m) do |struct|
|
45
|
+
struct_text = $2
|
46
|
+
struct = PKCS11::StructParser::CStruct.new( $3, [] )
|
47
|
+
|
48
|
+
struct_text.scan(/^\s+([A-Z_0-9]+)([\*\s]+)([\w_]+)\s*(\[\s*(\w+)\s*\])?/) do |elem|
|
49
|
+
type, name = $1, $3
|
50
|
+
qual = SIZE_CONSTANTS[$5] || $5
|
51
|
+
ptr = $2.include?('*')
|
52
|
+
type = "CK_ULONG" if ULONG_TYPES.include?(type)
|
53
|
+
type = "CK_ULONG_PTR" if ULONG_PTR_TYPES.include?(type)
|
54
|
+
struct.attrs << Attribute.new(ptr ? type+"_PTR" : type, name, qual)
|
55
|
+
end
|
56
|
+
structs << struct
|
57
|
+
end
|
58
|
+
end
|
59
|
+
return structs
|
60
|
+
end
|
61
|
+
|
62
|
+
def start!
|
63
|
+
@structs = parse_files(options.files)
|
64
|
+
@structs_by_name = @structs.inject({}){|sum, v| sum[v.name]=v; sum }
|
65
|
+
@std_structs_by_name = PKCS11_STD_STRUCTS.inject({}){|sum, v| sum[v.to_s]=true; sum }
|
66
|
+
|
67
|
+
write_files
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
if $0==__FILE__
|
75
|
+
PKCS11::Luna::StructParser.run(ARGV)
|
76
|
+
end
|
data/ext/generate_structs.rb
CHANGED
@@ -2,57 +2,67 @@
|
|
2
2
|
# Quick and dirty parser for PKCS#11 structs and
|
3
3
|
# generator for Ruby wrapper classes.
|
4
4
|
|
5
|
-
require '
|
6
|
-
require 'pkcs11'
|
7
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '../../ext/generate_structs'))
|
5
|
+
require 'optparse'
|
8
6
|
|
9
7
|
module PKCS11
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
8
|
+
class StructParser
|
9
|
+
|
10
|
+
attr_accessor :options
|
11
|
+
attr_accessor :structs
|
12
|
+
attr_accessor :structs_by_name
|
13
|
+
attr_accessor :std_structs_by_name
|
14
|
+
|
15
|
+
def self.run(argv)
|
16
|
+
s = self.new
|
17
|
+
options = Struct.new(:verbose, :def, :impl, :doc, :files).new
|
18
|
+
OptionParser.new do |opts|
|
19
|
+
opts.banner = "Usage: #{$0} [options] <header-file.h>*"
|
20
|
+
|
21
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely", &options.method(:verbose=))
|
22
|
+
opts.on("--def FILE", "Write struct definitions to this file", &options.method(:def=))
|
23
|
+
opts.on("--impl FILE", "Write struct implementations to this file", &options.method(:impl=))
|
24
|
+
opts.on("--doc FILE", "Write documentation to this file", &options.method(:doc=))
|
25
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
26
|
+
puts opts
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
end.parse!(argv)
|
30
|
+
options.files = argv
|
31
|
+
s.options = options
|
32
|
+
s.start!
|
33
|
+
end
|
34
|
+
|
35
|
+
CStruct = Struct.new(:name, :attrs)
|
36
|
+
Attribute = Struct.new(:type, :name, :qual, :mark)
|
37
|
+
IgnoreStructs = %w[CK_ATTRIBUTE CK_MECHANISM]
|
38
|
+
OnlyAllocatorStructs = %w[CK_MECHANISM_INFO CK_C_INITIALIZE_ARGS CK_INFO CK_SLOT_INFO CK_TOKEN_INFO CK_SESSION_INFO]
|
34
39
|
|
35
40
|
def struct_module
|
36
|
-
'PKCS11
|
41
|
+
'PKCS11'
|
37
42
|
end
|
38
43
|
|
39
|
-
|
44
|
+
class CStruct
|
45
|
+
def attr_by_sign(key)
|
46
|
+
attrs.find{|a| a.type+" "+a.name==key }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Attribute
|
51
|
+
def type_noptr
|
52
|
+
type.gsub(/_PTR$/,'')
|
53
|
+
end
|
54
|
+
end
|
40
55
|
|
41
56
|
def parse_files(files)
|
42
57
|
structs = []
|
43
58
|
files.each do |file_h|
|
44
59
|
c_src = IO.read(file_h)
|
45
|
-
c_src.scan(/struct\s+([A-Z_0-9]+)\s*\{(.*?)\}
|
60
|
+
c_src.scan(/struct\s+([A-Z_0-9]+)\s*\{(.*?)\}/m) do |struct|
|
46
61
|
struct_text = $2
|
47
|
-
struct =
|
48
|
-
|
49
|
-
struct_text.scan(/^\s+([A-Z_0-9]+)
|
50
|
-
|
51
|
-
qual = SIZE_CONSTANTS[$5] || $5
|
52
|
-
ptr = $2.include?('*')
|
53
|
-
type = "CK_ULONG" if ULONG_TYPES.include?(type)
|
54
|
-
type = "CK_ULONG_PTR" if ULONG_PTR_TYPES.include?(type)
|
55
|
-
struct.attrs << Attribute.new(ptr ? type+"_PTR" : type, name, qual)
|
62
|
+
struct = CStruct.new( $1, [] )
|
63
|
+
|
64
|
+
struct_text.scan(/^\s+([A-Z_0-9]+)\s+([\w_]+)\s*(\[\s*(\d+)\s*\])?/) do |elem|
|
65
|
+
struct.attrs << Attribute.new($1, $2, $4)
|
56
66
|
end
|
57
67
|
structs << struct
|
58
68
|
end
|
@@ -63,15 +73,145 @@ class StructParser < PKCS11::StructParser
|
|
63
73
|
def start!
|
64
74
|
@structs = parse_files(options.files)
|
65
75
|
@structs_by_name = @structs.inject({}){|sum, v| sum[v.name]=v; sum }
|
66
|
-
@std_structs_by_name =
|
76
|
+
@std_structs_by_name = @structs_by_name.dup
|
67
77
|
|
68
78
|
write_files
|
69
79
|
end
|
80
|
+
|
81
|
+
def array_attribute_names; ['pParams']; end
|
82
|
+
|
83
|
+
def write_files
|
84
|
+
File.open(options.def, "w") do |fd_def|
|
85
|
+
File.open(options.impl, "w") do |fd_impl|
|
86
|
+
File.open(options.doc, "w") do |fd_doc|
|
87
|
+
structs.each do |struct|
|
88
|
+
next if IgnoreStructs.include?(struct.name)
|
89
|
+
|
90
|
+
if OnlyAllocatorStructs.include?(struct.name)
|
91
|
+
fd_impl.puts "PKCS11_IMPLEMENT_ALLOCATOR(#{struct.name});"
|
92
|
+
else
|
93
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRUCT_WITH_ALLOCATOR(#{struct.name});"
|
94
|
+
end
|
95
|
+
fd_def.puts "PKCS11_DEFINE_STRUCT(#{struct.name});"
|
96
|
+
fd_doc.puts"class #{struct_module}::#{struct.name} < #{struct_module}::CStruct"
|
97
|
+
fd_doc.puts"# Size of corresponding C struct in bytes\nSIZEOF_STRUCT=Integer"
|
98
|
+
fd_doc.puts"# @return [String] Binary copy of the C struct\ndef to_s; end"
|
99
|
+
fd_doc.puts"# @return [Array<String>] Attributes of this struct\ndef members; end"
|
100
|
+
|
101
|
+
# find attributes belonging together for array of struct
|
102
|
+
struct.attrs.select{|attr| structs_by_name[attr.type_noptr] || std_structs_by_name[attr.type_noptr] }.each do |attr|
|
103
|
+
if array_attribute_names.include?(attr.name) && (len_attr = struct.attr_by_sign("CK_ULONG ulCount") || struct.attr_by_sign("CK_ULONG count") || struct.attr_by_sign("CK_ULONG #{attr.name}Count"))
|
104
|
+
std_struct = "PKCS11_" if std_structs_by_name[attr.type_noptr]
|
105
|
+
fd_impl.puts "PKCS11_IMPLEMENT_#{std_struct}STRUCT_PTR_ARRAY_ACCESSOR(#{struct.name}, #{attr.type_noptr}, #{attr.name}, #{len_attr.name});"
|
106
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
107
|
+
fd_doc.puts"# @return [Array<PKCS11::#{attr.type_noptr}>] accessor for #{attr.name} and #{len_attr.name}\nattr_accessor :#{attr.name}"
|
108
|
+
len_attr.mark = true
|
109
|
+
attr.mark = true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
# find string attributes belonging together
|
113
|
+
struct.attrs.select{|attr| ['CK_BYTE_PTR', 'CK_VOID_PTR', 'CK_UTF8CHAR_PTR', 'CK_CHAR_PTR'].include?(attr.type) }.each do |attr|
|
114
|
+
enco = case attr.type
|
115
|
+
when 'CK_UTF8CHAR_PTR' then 'utf8'
|
116
|
+
when 'CK_CHAR_PTR' then 'usascii'
|
117
|
+
when 'CK_BYTE_PTR', 'CK_VOID_PTR' then 'ascii8bit'
|
118
|
+
else raise "unexpected type #{attr.type.inspect}"
|
119
|
+
end
|
120
|
+
if len_attr=struct.attr_by_sign("CK_ULONG #{attr.name.gsub(/^p([A-Z])/){ "ul"+$1 }}Len")
|
121
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRING_PTR_LEN_ACCESSOR(#{struct.name}, #{attr.name}, #{len_attr.name}, #{enco});"
|
122
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
123
|
+
fd_doc.puts"# @return [#{enco.upcase}-String, nil] accessor for #{attr.name} and #{len_attr.name}\nattr_accessor :#{attr.name}"
|
124
|
+
len_attr.mark = true
|
125
|
+
elsif attr.name=='pData' && (len_attr = struct.attr_by_sign("CK_ULONG length") || struct.attr_by_sign("CK_ULONG ulLen"))
|
126
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRING_PTR_LEN_ACCESSOR(#{struct.name}, #{attr.name}, #{len_attr.name}, #{enco});"
|
127
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
128
|
+
fd_doc.puts"# @return [#{enco.upcase}-String, nil] accessor for #{attr.name} and #{len_attr.name}\nattr_accessor :#{attr.name}"
|
129
|
+
len_attr.mark = true
|
130
|
+
else
|
131
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRING_PTR_ACCESSOR(#{struct.name}, #{attr.name}, #{enco});"
|
132
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
133
|
+
fd_doc.puts"# @return [#{enco.upcase}-String, nil] accessor for #{attr.name}\nattr_accessor :#{attr.name}"
|
134
|
+
end
|
135
|
+
attr.mark = true
|
136
|
+
end
|
137
|
+
|
138
|
+
# standalone attributes
|
139
|
+
struct.attrs.reject{|a| a.mark }.each do |attr|
|
140
|
+
if attr.qual
|
141
|
+
# Attributes with qualifier
|
142
|
+
enco = case attr.type
|
143
|
+
when 'CK_BYTE' then 'ascii8bit'
|
144
|
+
when 'CK_UTF8CHAR' then 'utf8'
|
145
|
+
when 'CK_CHAR' then 'usascii'
|
146
|
+
end
|
147
|
+
case attr.type
|
148
|
+
when 'CK_BYTE', 'CK_UTF8CHAR', 'CK_CHAR'
|
149
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRING_ACCESSOR(#{struct.name}, #{attr.name}, #{enco});"
|
150
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
151
|
+
fd_doc.puts"# @return [#{enco.upcase}-String] accessor for #{attr.name} (max #{attr.qual} bytes)\nattr_accessor :#{attr.name}"
|
152
|
+
else
|
153
|
+
fd_impl.puts "/* unimplemented attr #{attr.type} #{attr.name} #{attr.qual} */"
|
154
|
+
fd_def.puts "/* unimplemented attr #{attr.type} #{attr.name} #{attr.qual} */"
|
155
|
+
end
|
156
|
+
else
|
157
|
+
case attr.type
|
158
|
+
when 'CK_BYTE'
|
159
|
+
fd_impl.puts "PKCS11_IMPLEMENT_BYTE_ACCESSOR(#{struct.name}, #{attr.name});"
|
160
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
161
|
+
fd_doc.puts"# @return [Integer] accessor for #{attr.name} (CK_BYTE)\nattr_accessor :#{attr.name}"
|
162
|
+
when 'CK_ULONG', 'CK_FLAGS', 'CK_SLOT_ID', 'CK_STATE', /CK_[A-Z_0-9]+_TYPE/
|
163
|
+
fd_impl.puts "PKCS11_IMPLEMENT_ULONG_ACCESSOR(#{struct.name}, #{attr.name});"
|
164
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
165
|
+
fd_doc.puts"# @return [Integer] accessor for #{attr.name} (CK_ULONG)\nattr_accessor :#{attr.name}"
|
166
|
+
when 'CK_OBJECT_HANDLE'
|
167
|
+
fd_impl.puts "PKCS11_IMPLEMENT_HANDLE_ACCESSOR(#{struct.name}, #{attr.name});"
|
168
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
169
|
+
fd_doc.puts"# @return [Integer, PKCS11::Object] Object handle (CK_ULONG)\nattr_accessor :#{attr.name}"
|
170
|
+
when 'CK_BBOOL'
|
171
|
+
fd_impl.puts "PKCS11_IMPLEMENT_BOOL_ACCESSOR(#{struct.name}, #{attr.name});"
|
172
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
173
|
+
fd_doc.puts"# @return [Boolean] Bool value\nattr_accessor :#{attr.name}"
|
174
|
+
when 'CK_ULONG_PTR'
|
175
|
+
fd_impl.puts "PKCS11_IMPLEMENT_ULONG_PTR_ACCESSOR(#{struct.name}, #{attr.name});"
|
176
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
177
|
+
fd_doc.puts"# @return [Integer, nil] accessor for #{attr.name} (CK_ULONG_PTR)\nattr_accessor :#{attr.name}"
|
178
|
+
else
|
179
|
+
# Struct attributes
|
180
|
+
if structs_by_name[attr.type]
|
181
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRUCT_ACCESSOR(#{struct.name}, #{attr.type}, #{attr.name});"
|
182
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
183
|
+
fd_doc.puts"# @return [#{struct_module}::#{attr.type}] inline struct\nattr_accessor :#{attr.name}"
|
184
|
+
elsif structs_by_name[attr.type_noptr]
|
185
|
+
fd_impl.puts "PKCS11_IMPLEMENT_STRUCT_PTR_ACCESSOR(#{struct.name}, #{attr.type_noptr}, #{attr.name});"
|
186
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
187
|
+
fd_doc.puts"# @return [#{struct_module}::#{attr.type_noptr}, nil] pointer to struct\nattr_accessor :#{attr.name}"
|
188
|
+
elsif std_structs_by_name[attr.type]
|
189
|
+
fd_impl.puts "PKCS11_IMPLEMENT_PKCS11_STRUCT_ACCESSOR(#{struct.name}, #{attr.type}, #{attr.name});"
|
190
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
191
|
+
fd_doc.puts"# @return [PKCS11::#{attr.type}] inline struct (see pkcs11.gem)\nattr_accessor :#{attr.name}"
|
192
|
+
elsif std_structs_by_name[attr.type_noptr]
|
193
|
+
fd_impl.puts "PKCS11_IMPLEMENT_PKCS11_STRUCT_PTR_ACCESSOR(#{struct.name}, #{attr.type_noptr}, #{attr.name});"
|
194
|
+
fd_def.puts "PKCS11_DEFINE_MEMBER(#{struct.name}, #{attr.name});"
|
195
|
+
fd_doc.puts"# @return [PKCS11::#{attr.type_noptr}, nil] pointer to struct (see pkcs11.gem)\nattr_accessor :#{attr.name}"
|
196
|
+
else
|
197
|
+
fd_impl.puts "/* unimplemented attr #{attr.type} #{attr.name} #{attr.qual} */"
|
198
|
+
fd_def.puts "/* unimplemented attr #{attr.type} #{attr.name} #{attr.qual} */"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
fd_impl.puts
|
205
|
+
fd_def.puts
|
206
|
+
fd_doc.puts "end"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
70
212
|
end
|
71
213
|
end
|
72
|
-
end
|
73
|
-
|
74
214
|
|
75
215
|
if $0==__FILE__
|
76
|
-
PKCS11::
|
216
|
+
PKCS11::StructParser.run(ARGV)
|
77
217
|
end
|