pkcs11 0.1.0-x86-mswin32 → 0.2.0-x86-mswin32
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/lib/1.8/pkcs11_ext.so
CHANGED
Binary file
|
data/lib/1.9/pkcs11_ext.so
CHANGED
Binary file
|
data/lib/pkcs11.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
require "#{major_minor}/pkcs11_ext"
|
8
|
-
else
|
9
|
-
require 'pkcs11_ext'
|
10
|
-
end
|
3
|
+
# Extend the search path for Windows binary gem, depending of the current ruby version
|
4
|
+
major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or
|
5
|
+
raise "Oops, can't extract the major/minor version from #{RUBY_VERSION.dump}"
|
6
|
+
$: << File.join(File.dirname(__FILE__), major_minor)
|
11
7
|
|
8
|
+
require 'pkcs11_ext'
|
12
9
|
require 'pkcs11/extensions'
|
data/lib/pkcs11/extensions.rb
CHANGED
@@ -7,14 +7,13 @@ require 'pkcs11/object'
|
|
7
7
|
#
|
8
8
|
# This library allowes to use PKCS#11 librarys in Ruby MRI.
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
10
|
+
# @example
|
12
11
|
# pkcs11 = PKCS11.open("/path/to/pkcs11.so")
|
13
12
|
# slot = pkcs11.active_slots.first
|
14
13
|
# p slot.info
|
15
14
|
# session = slot.open(PKCS11::CKF_SERIAL_SESSION|PKCS11::CKF_RW_SESSION)
|
16
15
|
# session.login(:USER, "1234")
|
17
|
-
# ...
|
16
|
+
# # ... crypto operations
|
18
17
|
# session.logout
|
19
18
|
# session.close
|
20
19
|
#
|
@@ -25,136 +24,45 @@ module PKCS11
|
|
25
24
|
# Open a PKCS#11 library file.
|
26
25
|
alias new open
|
27
26
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
(self.methods - ::Object.new.methods - InspectableStruct.instance_methods).grep(/[^=]$/).sort
|
33
|
-
end
|
34
|
-
# Array of the InspectableStruct's attribute values.
|
27
|
+
|
28
|
+
# Base class of all PKCS#11 structs.
|
29
|
+
class CStruct
|
30
|
+
# @return [Array<String>] attribute names
|
35
31
|
def values
|
36
32
|
members.inject([]){|a,v| a << send(v) }
|
37
33
|
end
|
38
|
-
# Hash with
|
34
|
+
# @return [Hash] with attribute names and current values
|
39
35
|
def to_hash
|
40
36
|
members.inject({}){|h,v| h[v.intern] = send(v); h }
|
41
37
|
end
|
42
|
-
def inspect
|
38
|
+
def inspect
|
43
39
|
"#<#{self.class} #{to_hash.map{|k,v| "#{k}=#{v.inspect}"}.join(", ") }>"
|
44
40
|
end
|
45
41
|
end
|
46
42
|
|
47
|
-
|
48
|
-
|
43
|
+
# Struct to hold an attribute type and it's value.
|
44
|
+
#
|
45
|
+
# @see PKCS11::Object
|
46
|
+
class CK_ATTRIBUTE
|
47
|
+
# @return [Array<String>] attribute names
|
49
48
|
def members
|
50
49
|
['type', 'value']
|
51
50
|
end
|
52
|
-
# Array
|
51
|
+
# @return [Array<String, Boolean, Integer>] attribute values
|
53
52
|
def values
|
54
53
|
members.inject([]){|a,v| a << send(v) }
|
55
54
|
end
|
56
|
-
# Hash with
|
55
|
+
# @return [Hash] with attribute names and current values
|
57
56
|
def to_hash
|
58
57
|
members.inject({}){|h,v| h[v.intern] = send(v); h }
|
59
58
|
end
|
60
59
|
# Get the constant name as String of the given value.
|
61
|
-
# Returns <tt>nil</tt> if value is unknown
|
60
|
+
# @return [String, nil] Returns <tt>nil</tt> if value is unknown
|
62
61
|
def to_s
|
63
62
|
ATTRIBUTES[type]
|
64
63
|
end
|
65
|
-
def inspect # :nodoc:
|
66
|
-
"#<#{self.class} #{ to_s ? "#{to_s} (#{type})" : type} value=#{value.inspect}>"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# See InspectableStruct.
|
71
|
-
class CK_INFO
|
72
|
-
include InspectableStruct
|
73
|
-
end
|
74
|
-
# See InspectableStruct.
|
75
|
-
class CK_C_INITIALIZE_ARGS
|
76
|
-
include InspectableStruct
|
77
|
-
end
|
78
|
-
# See InspectableStruct.
|
79
|
-
class CK_ATTRIBUTE
|
80
|
-
include InspectableAttribute
|
81
|
-
end
|
82
|
-
# See InspectableStruct.
|
83
|
-
class CK_TOKEN_INFO
|
84
|
-
include InspectableStruct
|
85
|
-
end
|
86
|
-
# See InspectableStruct.
|
87
|
-
class CK_SLOT_INFO
|
88
|
-
include InspectableStruct
|
89
|
-
end
|
90
|
-
# See InspectableStruct.
|
91
|
-
class CK_MECHANISM_INFO
|
92
|
-
include InspectableStruct
|
93
|
-
end
|
94
|
-
# See InspectableStruct.
|
95
|
-
class CK_SESSION_INFO
|
96
|
-
include InspectableStruct
|
97
|
-
end
|
98
|
-
# See InspectableStruct.
|
99
|
-
class CK_MECHANISM
|
100
|
-
include InspectableStruct
|
101
|
-
end
|
102
|
-
|
103
|
-
class ConstValue
|
104
|
-
def initialize(enum_hash, value) # :nodoc:
|
105
|
-
@enum_hash, @value = enum_hash, value
|
106
|
-
end
|
107
|
-
|
108
|
-
# Get the constant name as String of the given value.
|
109
|
-
# Returns <tt>nil</tt> if value is unknown.
|
110
|
-
def to_s
|
111
|
-
@enum_hash[@value]
|
112
|
-
end
|
113
64
|
def inspect
|
114
|
-
|
115
|
-
@value.inspect
|
116
|
-
end
|
117
|
-
|
118
|
-
# The value of the constant.
|
119
|
-
def to_int
|
120
|
-
@value
|
121
|
-
end
|
122
|
-
alias to_i to_int
|
123
|
-
end
|
124
|
-
|
125
|
-
module ConstValueHash # :nodoc:
|
126
|
-
def [](value)
|
127
|
-
super(value.to_int)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
class << self
|
132
|
-
def extend_ConstValueHash(hash_symb) # :nodoc:
|
133
|
-
# The MECHANISMS, ATTRIBUTES, etc. Hashs are freezed.
|
134
|
-
# So, we have make a copy, to extend the class.
|
135
|
-
my_HASH = const_get(hash_symb).dup
|
136
|
-
my_HASH.extend ConstValueHash
|
137
|
-
my_HASH.freeze
|
138
|
-
const_set("UNWRAPPED_#{hash_symb}", hash_symb)
|
139
|
-
remove_const(hash_symb)
|
140
|
-
const_set(hash_symb, my_HASH)
|
65
|
+
"#<#{self.class} #{ to_s ? "#{to_s} (#{type})" : type} value=#{value.inspect}>"
|
141
66
|
end
|
142
|
-
private :extend_ConstValueHash
|
143
|
-
end
|
144
|
-
|
145
|
-
extend_ConstValueHash(:OBJECT_CLASSES)
|
146
|
-
class ObjectClass < ConstValue
|
147
67
|
end
|
148
|
-
|
149
|
-
extend_ConstValueHash(:ATTRIBUTES)
|
150
|
-
class Attribute < ConstValue
|
151
|
-
end
|
152
|
-
|
153
|
-
extend_ConstValueHash(:MECHANISMS)
|
154
|
-
class Mechanism < ConstValue
|
155
|
-
end
|
156
|
-
|
157
|
-
# extend_ConstValueHash(:RETURN_VALUES)
|
158
|
-
# class ReturnValue < ConstValue
|
159
|
-
# end
|
160
68
|
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module PKCS11
|
2
|
+
# Some functions internaly used to make the API more convenient.
|
3
|
+
# @private
|
4
|
+
module Helper # :nodoc:
|
5
|
+
private
|
6
|
+
|
7
|
+
MechanismParameters = {
|
8
|
+
CKM_RSA_PKCS_OAEP => CK_RSA_PKCS_OAEP_PARAMS,
|
9
|
+
CKM_RSA_PKCS_PSS => CK_RSA_PKCS_PSS_PARAMS,
|
10
|
+
CKM_SHA1_RSA_PKCS_PSS => CK_RSA_PKCS_PSS_PARAMS,
|
11
|
+
CKM_SHA256_RSA_PKCS_PSS => CK_RSA_PKCS_PSS_PARAMS,
|
12
|
+
CKM_SHA384_RSA_PKCS_PSS => CK_RSA_PKCS_PSS_PARAMS,
|
13
|
+
CKM_SHA512_RSA_PKCS_PSS => CK_RSA_PKCS_PSS_PARAMS,
|
14
|
+
CKM_ECDH1_DERIVE => CK_ECDH1_DERIVE_PARAMS,
|
15
|
+
CKM_ECDH1_COFACTOR_DERIVE => CK_ECDH1_DERIVE_PARAMS,
|
16
|
+
CKM_ECMQV_DERIVE => CK_ECMQV_DERIVE_PARAMS,
|
17
|
+
CKM_X9_42_DH_DERIVE => CK_X9_42_DH1_DERIVE_PARAMS,
|
18
|
+
# CKM_X9_42_MQV_DERIVE => CK_X9_42_DH2_DERIVE_PARAMS,
|
19
|
+
CKM_X9_42_DH_HYBRID_DERIVE => CK_X9_42_DH2_DERIVE_PARAMS,
|
20
|
+
CKM_X9_42_MQV_DERIVE => CK_X9_42_MQV_DERIVE_PARAMS,
|
21
|
+
CKM_KEA_KEY_DERIVE => CK_KEA_DERIVE_PARAMS,
|
22
|
+
CKM_RC2_CBC => CK_RC2_CBC_PARAMS,
|
23
|
+
CKM_RC2_CBC_PAD => CK_RC2_CBC_PARAMS,
|
24
|
+
CKM_RC2_MAC_GENERAL => CK_RC2_MAC_GENERAL_PARAMS,
|
25
|
+
CKM_RC5_MAC => CK_RC5_PARAMS,
|
26
|
+
CKM_RC5_ECB => CK_RC5_PARAMS,
|
27
|
+
CKM_RC5_CBC => CK_RC5_CBC_PARAMS,
|
28
|
+
CKM_RC5_CBC_PAD => CK_RC5_CBC_PARAMS,
|
29
|
+
CKM_RC5_MAC_GENERAL => CK_RC5_MAC_GENERAL_PARAMS,
|
30
|
+
|
31
|
+
CKM_SKIPJACK_PRIVATE_WRAP => CK_SKIPJACK_PRIVATE_WRAP_PARAMS,
|
32
|
+
CKM_SKIPJACK_RELAYX => CK_SKIPJACK_RELAYX_PARAMS,
|
33
|
+
CKM_PBE_MD2_DES_CBC => CK_PBE_PARAMS,
|
34
|
+
CKM_PBE_MD5_DES_CBC => CK_PBE_PARAMS,
|
35
|
+
CKM_PBE_MD5_CAST_CBC => CK_PBE_PARAMS,
|
36
|
+
CKM_PBE_MD5_CAST3_CBC => CK_PBE_PARAMS,
|
37
|
+
CKM_PBE_MD5_CAST5_CBC => CK_PBE_PARAMS,
|
38
|
+
CKM_PBE_MD5_CAST128_CBC => CK_PBE_PARAMS,
|
39
|
+
CKM_PBE_SHA1_CAST5_CBC => CK_PBE_PARAMS,
|
40
|
+
CKM_PBE_SHA1_CAST128_CBC => CK_PBE_PARAMS,
|
41
|
+
CKM_PBE_SHA1_RC4_128 => CK_PBE_PARAMS,
|
42
|
+
CKM_PBE_SHA1_RC4_40 => CK_PBE_PARAMS,
|
43
|
+
CKM_PBE_SHA1_DES3_EDE_CBC => CK_PBE_PARAMS,
|
44
|
+
CKM_PBE_SHA1_DES2_EDE_CBC => CK_PBE_PARAMS,
|
45
|
+
CKM_PBE_SHA1_RC2_128_CBC => CK_PBE_PARAMS,
|
46
|
+
CKM_PBE_SHA1_RC2_40_CBC => CK_PBE_PARAMS,
|
47
|
+
CKM_PBA_SHA1_WITH_SHA1_HMAC => CK_PBE_PARAMS,
|
48
|
+
CKM_PKCS5_PBKD2 => CK_PKCS5_PBKD2_PARAMS,
|
49
|
+
CKM_KEY_WRAP_SET_OAEP => CK_KEY_WRAP_SET_OAEP_PARAMS,
|
50
|
+
CKM_SSL3_MASTER_KEY_DERIVE => CK_SSL3_RANDOM_DATA,
|
51
|
+
CKM_SSL3_KEY_AND_MAC_DERIVE => CK_SSL3_RANDOM_DATA,
|
52
|
+
CKM_SSL3_MASTER_KEY_DERIVE => CK_SSL3_MASTER_KEY_DERIVE_PARAMS,
|
53
|
+
CKM_SSL3_KEY_AND_MAC_DERIVE => CK_SSL3_KEY_MAT_OUT,
|
54
|
+
CKM_SSL3_KEY_AND_MAC_DERIVE => CK_SSL3_KEY_MAT_PARAMS,
|
55
|
+
CKM_TLS_MASTER_KEY_DERIVE => CK_SSL3_MASTER_KEY_DERIVE_PARAMS,
|
56
|
+
CKM_TLS_PRF => CK_TLS_PRF_PARAMS,
|
57
|
+
CKM_WTLS_MASTER_KEY_DERIVE => CK_WTLS_RANDOM_DATA,
|
58
|
+
CKM_WTLS_MASTER_KEY_DERIVE => CK_WTLS_MASTER_KEY_DERIVE_PARAMS,
|
59
|
+
CKM_WTLS_PRF => CK_WTLS_PRF_PARAMS,
|
60
|
+
CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE => CK_WTLS_KEY_MAT_PARAMS,
|
61
|
+
CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE => CK_WTLS_KEY_MAT_PARAMS,
|
62
|
+
CKM_CMS_SIG => CK_CMS_SIG_PARAMS,
|
63
|
+
|
64
|
+
CKM_DES_ECB_ENCRYPT_DATA => CK_KEY_DERIVATION_STRING_DATA,
|
65
|
+
CKM_DES_CBC_ENCRYPT_DATA => CK_DES_CBC_ENCRYPT_DATA_PARAMS,
|
66
|
+
CKM_DES3_ECB_ENCRYPT_DATA => CK_KEY_DERIVATION_STRING_DATA,
|
67
|
+
CKM_DES3_CBC_ENCRYPT_DATA => CK_DES_CBC_ENCRYPT_DATA_PARAMS,
|
68
|
+
CKM_AES_ECB_ENCRYPT_DATA => CK_KEY_DERIVATION_STRING_DATA,
|
69
|
+
CKM_AES_CBC_ENCRYPT_DATA => CK_AES_CBC_ENCRYPT_DATA_PARAMS,
|
70
|
+
CKM_CONCATENATE_BASE_AND_DATA => CK_KEY_DERIVATION_STRING_DATA,
|
71
|
+
CKM_CONCATENATE_DATA_AND_BASE => CK_KEY_DERIVATION_STRING_DATA,
|
72
|
+
CKM_XOR_BASE_AND_DATA => CK_KEY_DERIVATION_STRING_DATA,
|
73
|
+
|
74
|
+
CKM_ARIA_ECB_ENCRYPT_DATA => CK_KEY_DERIVATION_STRING_DATA,
|
75
|
+
CKM_ARIA_CBC_ENCRYPT_DATA => CK_ARIA_CBC_ENCRYPT_DATA_PARAMS,
|
76
|
+
|
77
|
+
CKM_SSL3_PRE_MASTER_KEY_GEN => CK_VERSION,
|
78
|
+
CKM_TLS_PRE_MASTER_KEY_GEN => CK_VERSION,
|
79
|
+
=begin
|
80
|
+
# for PKCS#11 v2.30
|
81
|
+
CKM_SEED_ECB_ENCRYPT_DATA => CK_KEY_DERIVATION_STRING_DATA,
|
82
|
+
CKM_SEED_CBC_ENCRYPT_DATA => CK_CBC_ENCRYPT_DATA_PARAMS,
|
83
|
+
CKM_GOSTR3410_KEY_WRAP => CK_GOSTR3410_KEY_WRAP_PARAMS,
|
84
|
+
CKM_GOSTR3410_DERIVE => CK_GOSTR3410_DERIVE_PARAMS,
|
85
|
+
CKM_GOSTR3410_KEY_WRAP => CK_GOSTR3410_KEY_WRAP_PARAMS,
|
86
|
+
=end
|
87
|
+
}
|
88
|
+
|
89
|
+
def to_attributes(template)
|
90
|
+
case template
|
91
|
+
when Array
|
92
|
+
template.map{|v| PKCS11::CK_ATTRIBUTE.new(string_to_handle('CKA_', v), nil) }
|
93
|
+
when Hash
|
94
|
+
template.map{|k,v| PKCS11::CK_ATTRIBUTE.new(string_to_handle('CKA_', k), v) }
|
95
|
+
when String, Symbol
|
96
|
+
[PKCS11::CK_ATTRIBUTE.new(string_to_handle('CKA_', template), nil)]
|
97
|
+
when Integer
|
98
|
+
[PKCS11::CK_ATTRIBUTE.new(template, nil)]
|
99
|
+
else
|
100
|
+
template
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def string_to_handle(prefix, attribute) # :nodoc:
|
105
|
+
case attribute
|
106
|
+
when String, Symbol
|
107
|
+
PKCS11.const_get("#{prefix}#{attribute}")
|
108
|
+
else
|
109
|
+
attribute
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def to_mechanism(mechanism) # :nodoc:
|
114
|
+
case mechanism
|
115
|
+
when String, Symbol
|
116
|
+
PKCS11::CK_MECHANISM.new(string_to_handle('CKM_', mechanism))
|
117
|
+
when Hash
|
118
|
+
raise "only one mechanism allowed" unless mechanism.length==1
|
119
|
+
|
120
|
+
mech = string_to_handle('CKM_', mechanism.keys.first)
|
121
|
+
param = mechanism.values.first
|
122
|
+
case param
|
123
|
+
when Hash
|
124
|
+
param_class = MechanismParameters[mech]
|
125
|
+
raise ArgumentError, "unknown mechanism - please use mechanism parameter as String" unless param_class
|
126
|
+
|
127
|
+
pa = param_class.new
|
128
|
+
param.each do |k, v|
|
129
|
+
pa.send "#{k}=", v
|
130
|
+
end
|
131
|
+
param = pa
|
132
|
+
end
|
133
|
+
|
134
|
+
PKCS11::CK_MECHANISM.new(mech, param)
|
135
|
+
when Fixnum
|
136
|
+
PKCS11::CK_MECHANISM.new(mechanism)
|
137
|
+
else
|
138
|
+
mechanism
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def to_mechanism_int(mechanism) # :nodoc:
|
143
|
+
case mechanism
|
144
|
+
when String, Symbol
|
145
|
+
PKCS11::MECHANISMS[string_to_handle('CKM_', mechanism)]
|
146
|
+
else
|
147
|
+
mechanism
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/lib/pkcs11/library.rb
CHANGED
@@ -1,13 +1,40 @@
|
|
1
1
|
module PKCS11
|
2
2
|
# A Library instance holds a handle to the opened PKCS#11 - dll or so file.
|
3
|
+
#
|
4
|
+
# == Low layer API
|
5
|
+
# The API of the binding consists of a lower layer, which
|
6
|
+
# is near to the PKCS#11 C interface, and a higher layer, which
|
7
|
+
# is more Ruby like and more comfortable. The low layer is currently
|
8
|
+
# not explicitly documented and is not recommented to use.
|
9
|
+
#
|
10
|
+
# All low layer PKCS#11 functions can be called on the {PKCS11::Library} object.
|
11
|
+
# Example for starting a session:
|
12
|
+
# pkcs11 = PKCS11.open("/path/to/pkcs11.so")
|
13
|
+
# slot = pkcs11.C_GetSlotList(true).first
|
14
|
+
# session = pkcs11.C_OpenSession(slot, PKCS11::CKF_SERIAL_SESSION | PKCS11::CKF_RW_SESSION)
|
15
|
+
# pkcs11.C_Login(session, PKCS11::CKU_USER, "password")
|
16
|
+
#
|
17
|
+
# The same on the high layer:
|
18
|
+
# pkcs11 = PKCS11.open("/path/to/pkcs11.so")
|
19
|
+
# session = pkcs11.active_slots.first.open
|
20
|
+
# session.login(:USER, "password")
|
3
21
|
class Library
|
22
|
+
# @private
|
4
23
|
alias unwrapped_initialize initialize # :nodoc:
|
5
24
|
|
6
25
|
# Load and initialize a pkcs11 dynamic library.
|
7
26
|
#
|
8
|
-
# so_path
|
9
|
-
# args
|
10
|
-
|
27
|
+
# @param [String, nil] so_path Path to the *.so or *.dll file to load.
|
28
|
+
# @param [Hash, CK_C_INITIALIZE_ARGS] args A Hash or CK_C_INITIALIZE_ARGS instance with load params.
|
29
|
+
#
|
30
|
+
# If so_path is +nil+ no library is loaded or initialized.
|
31
|
+
# In this case the calls to {#load_library}, {#C_GetFunctionList} and
|
32
|
+
# {#C_Initialize} have to be done manually, before using other methods:
|
33
|
+
# pkcs11 = PKCS11::Library.new
|
34
|
+
# pkcs11.load_library(so_path)
|
35
|
+
# pkcs11.C_GetFunctionList
|
36
|
+
# pkcs11.C_Initialize(args)
|
37
|
+
def initialize(so_path=nil, args={})
|
11
38
|
case args
|
12
39
|
when Hash
|
13
40
|
pargs = CK_C_INITIALIZE_ARGS.new
|
@@ -20,6 +47,7 @@ module PKCS11
|
|
20
47
|
|
21
48
|
alias unwrapped_C_GetInfo C_GetInfo
|
22
49
|
# Returns general information about Cryptoki.
|
50
|
+
# @return [CK_INFO]
|
23
51
|
def C_GetInfo
|
24
52
|
unwrapped_C_GetInfo
|
25
53
|
end
|
@@ -27,9 +55,12 @@ module PKCS11
|
|
27
55
|
|
28
56
|
alias unwrapped_C_GetSlotList C_GetSlotList
|
29
57
|
|
30
|
-
# Obtain an array of Slot objects in the system.
|
31
|
-
#
|
32
|
-
#
|
58
|
+
# Obtain an array of Slot objects in the system.
|
59
|
+
#
|
60
|
+
# @param [true, false] tokenPresent indicates whether the list
|
61
|
+
# obtained includes only those slots with a token present (true), or
|
62
|
+
# all slots (false);
|
63
|
+
# @return [Array<Slot>]
|
33
64
|
def C_GetSlotList(tokenPresent=true)
|
34
65
|
slots = unwrapped_C_GetSlotList(tokenPresent)
|
35
66
|
slots.map{|slot|
|
@@ -39,25 +70,25 @@ module PKCS11
|
|
39
70
|
alias slots C_GetSlotList
|
40
71
|
|
41
72
|
# Obtain an array of Slot objects in the system with a token present.
|
73
|
+
# @return [Array<Slot>]
|
42
74
|
def active_slots
|
43
75
|
slots(true)
|
44
76
|
end
|
45
77
|
|
46
78
|
# Obtain an array of Slot objects in the system regardless if a token is present.
|
79
|
+
# @return [Array<Slot>]
|
47
80
|
def all_slots
|
48
81
|
slots(false)
|
49
82
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
83
|
+
|
84
|
+
# Finalize and unload the library. If not called explicit, the library is freed by the GC.
|
85
|
+
def close
|
86
|
+
self.C_Finalize
|
87
|
+
self.unload_library
|
55
88
|
end
|
56
|
-
alias close C_Finalize
|
57
89
|
|
58
90
|
private :unwrapped_initialize
|
59
91
|
private :unwrapped_C_GetSlotList
|
60
|
-
private :unwrapped_C_Finalize
|
61
92
|
private :unwrapped_C_GetInfo
|
62
93
|
end
|
63
94
|
end
|
data/lib/pkcs11/object.rb
CHANGED
@@ -1,33 +1,47 @@
|
|
1
|
+
require 'pkcs11/helper'
|
2
|
+
|
1
3
|
module PKCS11
|
2
|
-
# Cryptoki
|
4
|
+
# Cryptoki's logical view of a token is a device that stores objects and can perform
|
3
5
|
# cryptographic functions. Cryptoki defines three classes of object: data, certificates, and
|
4
6
|
# keys.
|
5
7
|
#
|
6
8
|
# Attributes are characteristics that distinguish an instance of an object.
|
7
9
|
class Object
|
10
|
+
include Helper
|
11
|
+
|
12
|
+
# @private
|
8
13
|
def initialize(pkcs11, session, object) # :nodoc:
|
9
14
|
@pk, @sess, @obj = pkcs11, session, object
|
10
15
|
end
|
11
16
|
|
12
17
|
# The object handle.
|
18
|
+
# @return [Integer]
|
13
19
|
def to_int
|
14
20
|
@obj
|
15
21
|
end
|
16
22
|
alias to_i to_int
|
17
23
|
|
24
|
+
# @private
|
18
25
|
def inspect # :nodoc:
|
19
26
|
"#<#{self.class} #{@obj.inspect}>"
|
20
27
|
end
|
21
28
|
|
22
|
-
#
|
29
|
+
# Get the value of one attribute of the object.
|
23
30
|
#
|
24
|
-
# attribute
|
31
|
+
# @param [String, Symbol, Integer] attribute can be String or Symbol of the attribute constant
|
25
32
|
# or the attribute number as Integer.
|
26
33
|
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# Unknown attributes (out of PKCS#11 v2.2) are not converted
|
34
|
+
# @return [String, Integer, Boolean, nil] the attribute value as String, Integer or true/false
|
35
|
+
# depending on the attribute type.
|
36
|
+
# Unknown attributes (out of PKCS#11 v2.2) are not converted to adequate
|
37
|
+
# ruby objects but returned as String.
|
30
38
|
# That is true/false will be returned as "\\001" respectively "\\000".
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# object[:VALUE] # => "\000\000\000\000\000\000\000\000"
|
42
|
+
# object[:MODULUS_BITS] # => 768
|
43
|
+
#
|
44
|
+
# See PKCS#11 for attribute definitions.
|
31
45
|
def [](attribute)
|
32
46
|
attrs = C_GetAttributeValue( [attribute] )
|
33
47
|
attrs.first.value unless attrs.empty?
|
@@ -35,39 +49,52 @@ module PKCS11
|
|
35
49
|
|
36
50
|
# Modifies the value of one attribute the object.
|
37
51
|
#
|
38
|
-
# attribute
|
52
|
+
# @param [String, Symbol, Integer] attribute can be String or Symbol of the attribute constant
|
39
53
|
# or the attribute value as Integer.
|
40
|
-
#
|
54
|
+
# @param [String, Integer, Boolean, nil] value value the attribute will be set to.
|
41
55
|
#
|
42
|
-
# Following value conversations are done:
|
56
|
+
# Following value conversations are done from Ruby to C:
|
43
57
|
# true -> 0x01
|
44
58
|
# false -> 0x00
|
45
59
|
# nil -> NULL pointer
|
46
60
|
# Fixnum -> binary encoded unsigned long
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# object[:VALUE] = "\000\000\000\000\000\000\000\000"
|
64
|
+
# object[:MODULUS_BITS] = 768
|
65
|
+
#
|
66
|
+
# See PKCS#11 for attribute definitions.
|
67
|
+
# @return value
|
47
68
|
def []=(attribute, value)
|
48
69
|
C_SetAttributeValue( attribute => value )
|
70
|
+
value
|
49
71
|
end
|
50
72
|
|
51
73
|
# Modifies the value of one or more attributes of the object in a single call.
|
52
74
|
#
|
53
|
-
#
|
75
|
+
# @example
|
54
76
|
# object.attributes = {:SUBJECT => cert_subject, PKCS11::CKA_VALUE => cert_data}
|
77
|
+
# @return template
|
55
78
|
def C_SetAttributeValue(template={})
|
56
|
-
|
57
|
-
|
79
|
+
@pk.C_SetAttributeValue(@sess, @obj, to_attributes(template))
|
80
|
+
template
|
58
81
|
end
|
59
82
|
alias attributes= C_SetAttributeValue
|
60
83
|
|
61
84
|
# Obtains the value of one or more attributes of the object in a single call.
|
62
85
|
#
|
86
|
+
# @param [Array<String, Symbol, Integer>, Hash, String, Integer] attribute attribute names
|
87
|
+
# whose values should be returned
|
88
|
+
#
|
63
89
|
# Without params all known attributes are tried to read from the Object.
|
64
90
|
# This is significant slower then naming the needed attributes and should
|
65
91
|
# be used for debug purposes only.
|
66
92
|
#
|
67
|
-
#
|
93
|
+
# @return [Array<PKCS11::CK_ATTRIBUTE>] Requested attributes with values.
|
68
94
|
#
|
69
|
-
#
|
70
|
-
# certificate.attributes :
|
95
|
+
# @example
|
96
|
+
# certificate.attributes :VALUE, :CLASS
|
97
|
+
# => [#<PKCS11::CK_ATTRIBUTE CKA_VALUE (17) value="0\x82...">, #<PKCS11::CK_ATTRIBUTE CKA_CLASS (0) value=1>]
|
71
98
|
def C_GetAttributeValue(*template)
|
72
99
|
case template.length
|
73
100
|
when 0
|
@@ -80,21 +107,50 @@ module PKCS11
|
|
80
107
|
when 1
|
81
108
|
template = template[0]
|
82
109
|
end
|
83
|
-
template =
|
110
|
+
template = to_attributes template
|
84
111
|
@pk.C_GetAttributeValue(@sess, @obj, template)
|
85
112
|
end
|
86
113
|
alias attributes C_GetAttributeValue
|
87
|
-
|
114
|
+
|
115
|
+
# Copies an object, creating a new object for the copy.
|
116
|
+
#
|
117
|
+
# @param [Hash] template
|
118
|
+
#
|
119
|
+
# The template may specify new values for any attributes of the object that can ordinarily
|
120
|
+
# be modified (e.g., in the course of copying a secret key, a key's CKA_EXTRACTABLE
|
121
|
+
# attribute may be changed from true to false, but not the other way around.
|
122
|
+
# If this change is made, the new key's CKA_NEVER_EXTRACTABLE attribute will
|
123
|
+
# have the value false. Similarly, the template may specify that the new key's
|
124
|
+
# CKA_SENSITIVE attribute be true; the new key will have the same value for its
|
125
|
+
# CKA_ALWAYS_SENSITIVE attribute as the original key). It may also specify new
|
126
|
+
# values of the CKA_TOKEN and CKA_PRIVATE attributes (e.g., to copy a session
|
127
|
+
# object to a token object). If the template specifies a value of an attribute which is
|
128
|
+
# incompatible with other existing attributes of the object, the call fails with exception
|
129
|
+
# CKR_TEMPLATE_INCONSISTENT.
|
130
|
+
#
|
131
|
+
# Only session objects can be created during a read-only session. Only public objects can
|
132
|
+
# be created unless the normal user is logged in.
|
133
|
+
#
|
134
|
+
# @return [PKCS11::Object] the newly created object
|
135
|
+
def C_CopyObject(template={})
|
136
|
+
handle = @pk.C_CopyObject(@sess, @obj, to_attributes(template))
|
137
|
+
Object.new @pk, @sess, handle
|
138
|
+
end
|
139
|
+
alias copy C_CopyObject
|
140
|
+
|
88
141
|
# Destroys the object.
|
89
142
|
#
|
90
143
|
# Only session objects can be destroyed during a read-only session. Only public objects
|
91
144
|
# can be destroyed unless the normal user is logged in.
|
145
|
+
# @return [PKCS11::Object]
|
92
146
|
def C_DestroyObject()
|
93
147
|
@pk.C_DestroyObject(@sess, @obj)
|
148
|
+
self
|
94
149
|
end
|
95
150
|
alias destroy C_DestroyObject
|
96
151
|
|
97
152
|
# Gets the size of an object in bytes.
|
153
|
+
# @return [Integer]
|
98
154
|
def C_GetObjectSize()
|
99
155
|
@pk.C_GetObjectSize(@sess, @obj)
|
100
156
|
end
|