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