pkcs11_protect_server 0.2.3 → 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 +7 -0
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/Manifest.txt +2 -2
- data/README_PROTECT_SERVER.rdoc +3 -3
- data/Rakefile +30 -31
- data/ext/extconf.rb +10 -5
- data/ext/generate_constants.rb +30 -14
- data/ext/generate_protect_server_constants.rb +41 -0
- data/ext/generate_protect_server_structs.rb +74 -0
- data/ext/generate_structs.rb +182 -40
- data/ext/pk11_struct_macros.h +13 -13
- data/ext/pk11_version.h +1 -1
- data/ext/pk11s.c +1 -0
- data/ext/std_structs.rb +1 -0
- data/test/helper.rb +1 -1
- data/test/test_pkcs11_protect_server.rb +7 -7
- data/test/test_pkcs11_protect_server_crypt.rb +19 -19
- metadata +125 -122
- metadata.gz.sig +1 -0
- data/ext/pk11s_const_def.inc +0 -182
- data/ext/pk11s_struct.doc +0 -206
- data/ext/pk11s_struct_def.inc +0 -79
- data/ext/pk11s_struct_impl.inc +0 -79
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6fd43fb449a5dea77402583aac55585c11918fff2b61c05a836396c0c57349d1
|
4
|
+
data.tar.gz: 02c39243000b40517d52e9ed0440dcdeaddd7e1d61b755d0aec7f5a2fa31243e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 22662ee801a1b4eb0f6f6a1a21cda143d53b0cd1b63c68ff5f8d81275a96d2dbe380fae8e1e5911220928032f320a6b6b2fa163be544a36d317a47095770a68a
|
7
|
+
data.tar.gz: bd545b633cba8caf2318eb3145758eef9bbbb59ebff0ab1452dbd833e98b369c0b0750e05b097082e575bdd76a782112082c7137526cbf1ec78632048389bc44
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
ADDED
Binary file
|
data/Manifest.txt
CHANGED
@@ -4,8 +4,8 @@ Manifest.txt
|
|
4
4
|
README_PROTECT_SERVER.rdoc
|
5
5
|
Rakefile
|
6
6
|
ext/extconf.rb
|
7
|
-
ext/
|
8
|
-
ext/
|
7
|
+
ext/generate_protect_server_constants.rb
|
8
|
+
ext/generate_protect_server_structs.rb
|
9
9
|
ext/pk11s.c
|
10
10
|
lib/pkcs11_protect_server.rb
|
11
11
|
lib/pkcs11_protect_server/extensions.rb
|
data/README_PROTECT_SERVER.rdoc
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
= PKCS #11/Ruby Interface for Safenet Protect Server HSM
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
home :: http://github.com/larskanis/pkcs11
|
4
|
+
API documentation: http://pkcs11.rubyforge.org/pkcs11/
|
5
|
+
Safenet Protect Server HSM : http://www.safenet-inc.com
|
6
6
|
|
7
7
|
This ruby gem is an add-on to ruby-pkcs11[http://github.com/larskanis/pkcs11] .
|
8
8
|
It allowes to use Protect Server specific extensions, which are beyond the PKCS#11 standard.
|
data/Rakefile
CHANGED
@@ -7,35 +7,43 @@ require 'rake/extensiontask'
|
|
7
7
|
require 'rbconfig'
|
8
8
|
|
9
9
|
PROTECT_SERVER_SDK_DIR = ENV['PROTECT_SERVER_SDK_DIR'] || '/opt/ETcpsdk'
|
10
|
-
|
10
|
+
RUBY_PKCS11_DIR = File.expand_path('..')
|
11
|
+
$: << File.join(RUBY_PKCS11_DIR, "lib")
|
11
12
|
|
12
|
-
|
13
|
-
'ext/pk11s_struct_impl.inc',
|
14
|
-
'ext/pk11s_struct_def.inc',
|
15
|
-
'ext/pk11s_const_def.inc',
|
16
|
-
'ext/pk11s_struct.doc',
|
13
|
+
SHARED_FILES = [
|
17
14
|
'ext/pk11_struct_macros.h',
|
18
15
|
'ext/pk11_const_macros.h',
|
19
16
|
'ext/pk11_version.h',
|
17
|
+
'ext/generate_structs.rb',
|
18
|
+
'ext/generate_constants.rb',
|
19
|
+
]
|
20
|
+
GENERATED_FILES = [
|
21
|
+
"ext/std_structs.rb"
|
20
22
|
]
|
21
23
|
|
24
|
+
CLEAN.include SHARED_FILES
|
22
25
|
CLEAN.include GENERATED_FILES
|
23
26
|
CLEAN.include 'lib/pkcs11_protect_server_ext.so'
|
24
27
|
CLEAN.include 'tmp'
|
25
28
|
|
26
29
|
def pkcs11_version
|
27
|
-
file = File.join(
|
30
|
+
file = File.join(RUBY_PKCS11_DIR, 'ext/pk11_version.h')
|
28
31
|
version_re = /VERSION += +([\"\'])([\d][\d\w\.]+)\1/
|
29
32
|
File.read_utf(file)[version_re, 2]
|
30
33
|
end
|
31
34
|
|
35
|
+
# Ensure pkg is rebuilt
|
36
|
+
task :remove_pkg do
|
37
|
+
rm_rf 'pkg'
|
38
|
+
end
|
39
|
+
task :gem => [:remove_pkg]
|
40
|
+
|
32
41
|
hoe = Hoe.spec 'pkcs11_protect_server' do
|
33
42
|
developer('Lars Kanis', 'kanis@comcard.de')
|
34
43
|
extra_deps << ['pkcs11', "= #{pkcs11_version}"]
|
35
|
-
extra_dev_deps << ['yard', '
|
36
|
-
extra_dev_deps << ['rake-compiler', '
|
44
|
+
extra_dev_deps << ['yard', '~> 0.6']
|
45
|
+
extra_dev_deps << ['rake-compiler', '~> 0.7']
|
37
46
|
|
38
|
-
self.url = 'http://github.com/larskanis/pkcs11'
|
39
47
|
self.summary = 'Safenet-ProtectServer extensions for PKCS#11-Ruby'
|
40
48
|
self.description = 'This module allows Ruby programs to use vendor extensions for Safenet Protect Server.'
|
41
49
|
self.version = pkcs11_version
|
@@ -45,12 +53,10 @@ hoe = Hoe.spec 'pkcs11_protect_server' do
|
|
45
53
|
self.extra_rdoc_files << self.readme_file << 'ext/pk11s.c'
|
46
54
|
spec_extras[:extensions] = 'ext/extconf.rb'
|
47
55
|
spec_extras[:files] = File.read_utf("Manifest.txt").split(/\r?\n\r?/)
|
48
|
-
spec_extras[:files] += GENERATED_FILES
|
49
|
-
spec_extras[:
|
56
|
+
spec_extras[:files] += SHARED_FILES + GENERATED_FILES
|
57
|
+
spec_extras[:required_ruby_version] = '>= 2.2.0'
|
50
58
|
end
|
51
59
|
|
52
|
-
ENV['RUBY_CC_VERSION'] ||= '1.8.7:1.9.2'
|
53
|
-
|
54
60
|
Rake::ExtensionTask.new('pkcs11_protect_server_ext', hoe.spec) do |ext|
|
55
61
|
ext.ext_dir = 'ext'
|
56
62
|
ext.cross_compile = true # enable cross compilation (requires cross compile toolchain)
|
@@ -59,28 +65,21 @@ Rake::ExtensionTask.new('pkcs11_protect_server_ext', hoe.spec) do |ext|
|
|
59
65
|
ext.config_options << "--with-protect-server-sdk-dir=#{PROTECT_SERVER_SDK_DIR.inspect}"
|
60
66
|
end
|
61
67
|
|
62
|
-
|
63
|
-
|
64
|
-
|
68
|
+
# Add shared file from base pkcs11 gem
|
69
|
+
SHARED_FILES.each do |filename|
|
70
|
+
file filename => File.join(RUBY_PKCS11_DIR, filename) do |t|
|
71
|
+
cp t.prerequisites.first, t.name, verbose: true
|
65
72
|
end
|
73
|
+
file 'ext/extconf.rb' => filename
|
66
74
|
end
|
67
75
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
file 'ext/extconf.rb' => ['ext/pk11s_struct_def.inc', 'ext/pk11s_const_def.inc', 'ext/pk11_struct_macros.h', 'ext/pk11_const_macros.h', 'ext/pk11_version.h']
|
73
|
-
file 'ext/pk11s_struct_def.inc' => 'ext/generate_structs.rb' do
|
74
|
-
sh "#{RbConfig::CONFIG['ruby_install_name']} ext/generate_structs.rb --def ext/pk11s_struct_def.inc --impl ext/pk11s_struct_impl.inc --doc ext/pk11s_struct.doc #{File.join(PROTECT_SERVER_SDK_DIR, 'include/ctvdef.h').inspect}"
|
75
|
-
end
|
76
|
-
file 'ext/pk11s_struct_impl.inc' => 'ext/pk11s_struct_def.inc'
|
77
|
-
file 'ext/pk11s_struct.doc' => 'ext/pk11s_struct_def.inc'
|
76
|
+
file "ext/std_structs.rb" do |t|
|
77
|
+
require "pkcs11"
|
78
|
+
std_structs = PKCS11.constants.select{|c| PKCS11.const_get(c).respond_to?(:ancestors) && !(PKCS11.const_get(c).ancestors & [PKCS11::CStruct, PKCS11::CK_ATTRIBUTE]).empty? }
|
78
79
|
|
79
|
-
|
80
|
-
sh "#{RbConfig::CONFIG['ruby_install_name']} ext/generate_constants.rb --const ext/pk11s_const_def.inc #{File.join(PROTECT_SERVER_SDK_DIR, 'include/ctvdef.h').inspect}"
|
80
|
+
File.write t.name, "PKCS11_STD_STRUCTS = #{std_structs.inspect}"
|
81
81
|
end
|
82
|
-
file 'ext/pk11s.c' => ['ext/pk11s_struct_def.inc', 'ext/pk11s_struct_impl.inc', 'ext/pk11s_const_def.inc']
|
83
82
|
|
84
|
-
task :
|
83
|
+
task doc_files: 'ext/pk11s_struct.doc'
|
85
84
|
|
86
85
|
# vim: syntax=ruby
|
data/ext/extconf.rb
CHANGED
@@ -4,11 +4,16 @@ require "rubygems"
|
|
4
4
|
inc, lib = dir_config('protect-server-sdk', '/opt/ETcpsdk/include', '/opt/ETcpsdk/lib')
|
5
5
|
puts "using ProtectServer-SDK include:#{inc} lib:#{lib}"
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
require_relative "generate_protect_server_constants"
|
8
|
+
require_relative "generate_protect_server_structs"
|
9
|
+
|
10
|
+
args = ["--const", "pk11s_const_def.inc", File.join(inc, 'ctvdef.h')]
|
11
|
+
puts "running const parser with: #{args.join(" ")}"
|
12
|
+
PKCS11::ProtectServer::ConstantParser.run(args)
|
13
|
+
|
14
|
+
args = ["--def", "pk11s_struct_def.inc", "--impl", "pk11s_struct_impl.inc", "--doc", "pk11s_struct.doc", File.join(inc, 'ctvdef.h')]
|
15
|
+
puts "running struct parser with: #{args.join(" ")}"
|
16
|
+
PKCS11::ProtectServer::StructParser.run(args)
|
12
17
|
|
13
18
|
find_header('pk11_struct_macros.h')
|
14
19
|
find_header('pk11_const_macros.h')
|
data/ext/generate_constants.rb
CHANGED
@@ -2,20 +2,39 @@
|
|
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
37
|
|
17
|
-
IgnoreConstants = %w[CKR_CERTIFICATE_NOT_YET_ACTIVE CKR_CERTIFICATE_EXPIRED]
|
18
|
-
|
19
38
|
def start!
|
20
39
|
File.open(options.const, "w") do |fd_const|
|
21
40
|
options.files.each do |file_h|
|
@@ -23,8 +42,7 @@ class ConstantParser < PKCS11::ConstantParser
|
|
23
42
|
ConstGroups.each do |const_group|
|
24
43
|
c_src.scan(const_group.regexp) do
|
25
44
|
const_name, const_value = $1, $2
|
26
|
-
|
27
|
-
|
45
|
+
|
28
46
|
fd_const.puts "#{const_group.def}(#{const_name}); /* #{const_value} */"
|
29
47
|
end
|
30
48
|
end
|
@@ -33,9 +51,7 @@ class ConstantParser < PKCS11::ConstantParser
|
|
33
51
|
end
|
34
52
|
end
|
35
53
|
end
|
36
|
-
end
|
37
|
-
|
38
54
|
|
39
55
|
if $0==__FILE__
|
40
|
-
PKCS11::
|
56
|
+
PKCS11::ConstantParser.run(ARGV)
|
41
57
|
end
|
@@ -0,0 +1,41 @@
|
|
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 ProtectServer
|
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+(.+)/, 'PKCS11_DEFINE_RETURN_VALUE'),
|
15
|
+
]
|
16
|
+
|
17
|
+
IgnoreConstants = %w[CKR_CERTIFICATE_NOT_YET_ACTIVE CKR_CERTIFICATE_EXPIRED]
|
18
|
+
|
19
|
+
def start!
|
20
|
+
File.open(options.const, "w") do |fd_const|
|
21
|
+
options.files.each do |file_h|
|
22
|
+
c_src = IO.read(file_h)
|
23
|
+
ConstGroups.each do |const_group|
|
24
|
+
c_src.scan(const_group.regexp) do
|
25
|
+
const_name, const_value = $1, $2
|
26
|
+
next if IgnoreConstants.include?(const_name)
|
27
|
+
|
28
|
+
fd_const.puts "#{const_group.def}(#{const_name}); /* #{const_value} */"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
if $0==__FILE__
|
40
|
+
PKCS11::ProtectServer::ConstantParser.run(ARGV)
|
41
|
+
end
|
@@ -0,0 +1,74 @@
|
|
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 ProtectServer
|
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
|
+
}
|
28
|
+
|
29
|
+
ULONG_TYPES = %w[CK_COUNT CK_SIZE CK_TIMESTAMP_FORMAT]
|
30
|
+
ULONG_PTR_TYPES = %w[CK_COUNT_PTR]
|
31
|
+
|
32
|
+
def struct_module
|
33
|
+
'PKCS11::ProtectServer'
|
34
|
+
end
|
35
|
+
|
36
|
+
def array_attribute_names; %w[attributes mechanism certAttr hCert]; end
|
37
|
+
|
38
|
+
def parse_files(files)
|
39
|
+
structs = []
|
40
|
+
files.each do |file_h|
|
41
|
+
c_src = IO.read(file_h)
|
42
|
+
c_src.scan(/struct\s+([A-Z_0-9]+)\s*\{(.*?)\}/m) do |struct|
|
43
|
+
struct_text = $2
|
44
|
+
struct = PKCS11::StructParser::CStruct.new( $1, [] )
|
45
|
+
|
46
|
+
struct_text.scan(/^\s+([A-Z_0-9]+)([\*\s]+)([\w_]+)\s*(\[\s*(\w+)\s*\])?/) do |elem|
|
47
|
+
type, name = $1, $3
|
48
|
+
qual = SIZE_CONSTANTS[$5] || $5
|
49
|
+
ptr = $2.include?('*')
|
50
|
+
type = "CK_ULONG" if ULONG_TYPES.include?(type)
|
51
|
+
type = "CK_ULONG_PTR" if ULONG_PTR_TYPES.include?(type)
|
52
|
+
struct.attrs << Attribute.new(ptr ? type+"_PTR" : type, name, qual)
|
53
|
+
end
|
54
|
+
structs << struct
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return structs
|
58
|
+
end
|
59
|
+
|
60
|
+
def start!
|
61
|
+
@structs = parse_files(options.files)
|
62
|
+
@structs_by_name = @structs.inject({}){|sum, v| sum[v.name]=v; sum }
|
63
|
+
@std_structs_by_name = PKCS11_STD_STRUCTS.inject({}){|sum, v| sum[v.to_s]=true; sum }
|
64
|
+
|
65
|
+
write_files
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
if $0==__FILE__
|
73
|
+
PKCS11::ProtectServer::StructParser.run(ARGV)
|
74
|
+
end
|
data/ext/generate_structs.rb
CHANGED
@@ -2,39 +2,56 @@
|
|
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
|
-
|
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]
|
32
39
|
|
33
40
|
def struct_module
|
34
|
-
'PKCS11
|
41
|
+
'PKCS11'
|
35
42
|
end
|
36
43
|
|
37
|
-
|
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
|
38
55
|
|
39
56
|
def parse_files(files)
|
40
57
|
structs = []
|
@@ -42,15 +59,10 @@ class StructParser < PKCS11::StructParser
|
|
42
59
|
c_src = IO.read(file_h)
|
43
60
|
c_src.scan(/struct\s+([A-Z_0-9]+)\s*\{(.*?)\}/m) do |struct|
|
44
61
|
struct_text = $2
|
45
|
-
struct =
|
46
|
-
|
47
|
-
struct_text.scan(/^\s+([A-Z_0-9]+)
|
48
|
-
|
49
|
-
qual = SIZE_CONSTANTS[$5] || $5
|
50
|
-
ptr = $2.include?('*')
|
51
|
-
type = "CK_ULONG" if ULONG_TYPES.include?(type)
|
52
|
-
type = "CK_ULONG_PTR" if ULONG_PTR_TYPES.include?(type)
|
53
|
-
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)
|
54
66
|
end
|
55
67
|
structs << struct
|
56
68
|
end
|
@@ -61,15 +73,145 @@ class StructParser < PKCS11::StructParser
|
|
61
73
|
def start!
|
62
74
|
@structs = parse_files(options.files)
|
63
75
|
@structs_by_name = @structs.inject({}){|sum, v| sum[v.name]=v; sum }
|
64
|
-
@std_structs_by_name =
|
76
|
+
@std_structs_by_name = @structs_by_name.dup
|
65
77
|
|
66
78
|
write_files
|
67
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
|
68
212
|
end
|
69
213
|
end
|
70
|
-
end
|
71
|
-
|
72
214
|
|
73
215
|
if $0==__FILE__
|
74
|
-
PKCS11::
|
216
|
+
PKCS11::StructParser.run(ARGV)
|
75
217
|
end
|