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
         |