pkcs11 0.2.4-x64-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.tar.gz.sig +0 -0
- data/.autotest +23 -0
- data/.gemtest +0 -0
- data/.yardopts +1 -0
- data/History.txt +57 -0
- data/MIT-LICENSE +22 -0
- data/Manifest.txt +57 -0
- data/README.rdoc +205 -0
- data/Rakefile +111 -0
- data/ext/extconf.rb +7 -0
- data/ext/generate_constants.rb +57 -0
- data/ext/generate_structs.rb +206 -0
- data/ext/generate_thread_funcs.rb +72 -0
- data/ext/include/cryptoki.h +66 -0
- data/ext/include/ct-kip.h +50 -0
- data/ext/include/otp-pkcs11.h +125 -0
- data/ext/include/pkcs-11v2-20a3.h +124 -0
- data/ext/include/pkcs11.h +299 -0
- data/ext/include/pkcs11f.h +912 -0
- data/ext/include/pkcs11t.h +1885 -0
- data/ext/pk11.c +1675 -0
- data/ext/pk11.h +81 -0
- data/ext/pk11_const.c +205 -0
- data/ext/pk11_const_def.inc +452 -0
- data/ext/pk11_const_macros.h +38 -0
- data/ext/pk11_struct.doc +792 -0
- data/ext/pk11_struct_def.inc +302 -0
- data/ext/pk11_struct_impl.inc +302 -0
- data/ext/pk11_struct_macros.h +435 -0
- data/ext/pk11_thread_funcs.c +411 -0
- data/ext/pk11_thread_funcs.h +482 -0
- data/ext/pk11_version.h +6 -0
- data/lib/2.0/pkcs11_ext.so +0 -0
- data/lib/pkcs11.rb +9 -0
- data/lib/pkcs11/extensions.rb +68 -0
- data/lib/pkcs11/helper.rb +144 -0
- data/lib/pkcs11/library.rb +140 -0
- data/lib/pkcs11/object.rb +171 -0
- data/lib/pkcs11/session.rb +765 -0
- data/lib/pkcs11/slot.rb +102 -0
- data/pkcs11_protect_server/Manifest.txt +14 -0
- data/pkcs11_protect_server/README_PROTECT_SERVER.rdoc +89 -0
- data/test/fixtures/softokn/cert8.db +0 -0
- data/test/fixtures/softokn/key3.db +0 -0
- data/test/fixtures/softokn/secmod.db +0 -0
- data/test/helper.rb +58 -0
- data/test/test_pkcs11.rb +71 -0
- data/test/test_pkcs11_crypt.rb +220 -0
- data/test/test_pkcs11_object.rb +122 -0
- data/test/test_pkcs11_session.rb +123 -0
- data/test/test_pkcs11_slot.rb +78 -0
- data/test/test_pkcs11_structs.rb +166 -0
- data/test/test_pkcs11_thread.rb +44 -0
- metadata +213 -0
- metadata.gz.sig +0 -0
data/ext/pk11_version.h
ADDED
Binary file
|
data/lib/pkcs11.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
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)
|
7
|
+
|
8
|
+
require 'pkcs11_ext'
|
9
|
+
require 'pkcs11/extensions'
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'pkcs11/library'
|
2
|
+
require 'pkcs11/slot'
|
3
|
+
require 'pkcs11/session'
|
4
|
+
require 'pkcs11/object'
|
5
|
+
|
6
|
+
# Ruby connector to PKCS#11 libraries.
|
7
|
+
#
|
8
|
+
# This library allowes to use PKCS#11 librarys in Ruby MRI.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# pkcs11 = PKCS11.open("/path/to/pkcs11.so")
|
12
|
+
# slot = pkcs11.active_slots.first
|
13
|
+
# p slot.info
|
14
|
+
# session = slot.open(PKCS11::CKF_SERIAL_SESSION|PKCS11::CKF_RW_SESSION)
|
15
|
+
# session.login(:USER, "1234")
|
16
|
+
# # ... crypto operations
|
17
|
+
# session.logout
|
18
|
+
# session.close
|
19
|
+
#
|
20
|
+
# See unit tests in the <tt>test</tt> directory for further examples of the usage.
|
21
|
+
module PKCS11
|
22
|
+
|
23
|
+
class << self
|
24
|
+
# Open a PKCS#11 library file.
|
25
|
+
alias new open
|
26
|
+
end
|
27
|
+
|
28
|
+
# Base class of all PKCS#11 structs.
|
29
|
+
class CStruct
|
30
|
+
# @return [Array<String>] attribute names
|
31
|
+
def values
|
32
|
+
members.inject([]){|a,v| a << send(v) }
|
33
|
+
end
|
34
|
+
# @return [Hash] with attribute names and current values
|
35
|
+
def to_hash
|
36
|
+
members.inject({}){|h,v| h[v.intern] = send(v); h }
|
37
|
+
end
|
38
|
+
def inspect
|
39
|
+
"#<#{self.class} #{to_hash.map{|k,v| "#{k}=#{v.inspect}"}.join(", ") }>"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
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
|
48
|
+
def members
|
49
|
+
['type', 'value']
|
50
|
+
end
|
51
|
+
# @return [Array<String, Boolean, Integer>] attribute values
|
52
|
+
def values
|
53
|
+
members.inject([]){|a,v| a << send(v) }
|
54
|
+
end
|
55
|
+
# @return [Hash] with attribute names and current values
|
56
|
+
def to_hash
|
57
|
+
members.inject({}){|h,v| h[v.intern] = send(v); h }
|
58
|
+
end
|
59
|
+
# Get the constant name as String of the given value.
|
60
|
+
# @return [String, nil] Returns <tt>nil</tt> if value is unknown
|
61
|
+
def to_s
|
62
|
+
ATTRIBUTES[type]
|
63
|
+
end
|
64
|
+
def inspect
|
65
|
+
"#<#{self.class} #{ to_s ? "#{to_s} (#{type})" : type} value=#{value.inspect}>"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,144 @@
|
|
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| @pk.vendor_class_CK_ATTRIBUTE.new(string_to_handle('CKA_', v), nil) }
|
93
|
+
when Hash
|
94
|
+
template.map{|k,v| @pk.vendor_class_CK_ATTRIBUTE.new(string_to_handle('CKA_', k), v) }
|
95
|
+
when String, Symbol
|
96
|
+
[@pk.vendor_class_CK_ATTRIBUTE.new(string_to_handle('CKA_', template), nil)]
|
97
|
+
when Integer
|
98
|
+
[@pk.vendor_class_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
|
+
@pk.vendor_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 = @pk.vendor_mechanism_parameter_struct(mech)
|
125
|
+
raise ArgumentError, "unknown mechanism - please use String/Int/Struct as mechanism parameter" 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
|
+
when Bignum
|
138
|
+
PKCS11::CK_MECHANISM.new(mechanism)
|
139
|
+
else
|
140
|
+
mechanism
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module PKCS11
|
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")
|
21
|
+
class Library
|
22
|
+
# @private
|
23
|
+
alias unwrapped_initialize initialize # :nodoc:
|
24
|
+
|
25
|
+
# Load and initialize a pkcs11 dynamic library.
|
26
|
+
#
|
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={})
|
38
|
+
unwrapped_initialize(so_path, args)
|
39
|
+
end
|
40
|
+
|
41
|
+
alias unwrapped_C_Initialize C_Initialize
|
42
|
+
# Initialize a pkcs11 dynamic library.
|
43
|
+
#
|
44
|
+
# @param [Hash, CK_C_INITIALIZE_ARGS] args A Hash or CK_C_INITIALIZE_ARGS instance with load params.
|
45
|
+
def C_Initialize(args=nil)
|
46
|
+
case args
|
47
|
+
when Hash
|
48
|
+
pargs = CK_C_INITIALIZE_ARGS.new
|
49
|
+
args.each{|k,v| pargs.send("#{k}=", v) }
|
50
|
+
else
|
51
|
+
pargs = args
|
52
|
+
end
|
53
|
+
unwrapped_C_Initialize(pargs)
|
54
|
+
end
|
55
|
+
|
56
|
+
alias unwrapped_C_GetInfo C_GetInfo
|
57
|
+
# Returns general information about Cryptoki.
|
58
|
+
# @return [CK_INFO]
|
59
|
+
def C_GetInfo
|
60
|
+
unwrapped_C_GetInfo
|
61
|
+
end
|
62
|
+
alias info C_GetInfo
|
63
|
+
|
64
|
+
alias unwrapped_C_GetSlotList C_GetSlotList
|
65
|
+
|
66
|
+
# Obtain an array of Slot objects in the system.
|
67
|
+
#
|
68
|
+
# @param [true, false] tokenPresent indicates whether the list
|
69
|
+
# obtained includes only those slots with a token present (true), or
|
70
|
+
# all slots (false);
|
71
|
+
# @return [Array<Slot>]
|
72
|
+
def C_GetSlotList(tokenPresent=false)
|
73
|
+
slots = unwrapped_C_GetSlotList(tokenPresent)
|
74
|
+
slots.map{|slot|
|
75
|
+
Slot.new self, slot
|
76
|
+
}
|
77
|
+
end
|
78
|
+
alias slots C_GetSlotList
|
79
|
+
|
80
|
+
# Obtain an array of Slot objects in the system with a token present.
|
81
|
+
# @return [Array<Slot>]
|
82
|
+
def active_slots
|
83
|
+
slots(true)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Obtain an array of Slot objects in the system regardless if a token is present.
|
87
|
+
# @return [Array<Slot>]
|
88
|
+
def all_slots
|
89
|
+
slots(false)
|
90
|
+
end
|
91
|
+
|
92
|
+
alias unwrapped_C_WaitForSlotEvent C_WaitForSlotEvent
|
93
|
+
|
94
|
+
# Waits for a slot event, such as token insertion or token removal, to occur.
|
95
|
+
#
|
96
|
+
# @param [Integer] flags determines whether or not the C_WaitForSlotEvent call blocks (i.e., waits
|
97
|
+
# for a slot event to occur);
|
98
|
+
# At present, the only flag defined for use in the flags argument is PKCS11::CKF_DONT_BLOCK
|
99
|
+
# @return [Slot, nil] the slot that the event occurred in; nil if no event occured (CKR_NO_EVENT)
|
100
|
+
def C_WaitForSlotEvent(flags=0)
|
101
|
+
slot = unwrapped_C_WaitForSlotEvent(flags)
|
102
|
+
slot ? Slot.new(self, slot) : nil
|
103
|
+
end
|
104
|
+
alias wait_for_slot_event C_WaitForSlotEvent
|
105
|
+
|
106
|
+
# Finalize and unload the library. If not called explicit, the library is freed by the GC.
|
107
|
+
def close
|
108
|
+
self.C_Finalize
|
109
|
+
self.unload_library
|
110
|
+
end
|
111
|
+
|
112
|
+
# Return the value of a named constant. Used for CKA_* and CKM_* .
|
113
|
+
# This method could be overloaded for vendor specific extensions.
|
114
|
+
#
|
115
|
+
# @param [String] name Name of the constant
|
116
|
+
# @return [Integer] Value of the constant
|
117
|
+
def vendor_const_get(name)
|
118
|
+
PKCS11.const_get(name)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Return an array of all known CKA_* attributes as String.
|
122
|
+
# This method could be overloaded for vendor specific extensions.
|
123
|
+
def vendor_all_attribute_names
|
124
|
+
return ATTRIBUTES.values
|
125
|
+
end
|
126
|
+
|
127
|
+
# Return the parameter struct of a given mechanism.
|
128
|
+
# This method could be overloaded for vendor specific extensions.
|
129
|
+
#
|
130
|
+
# @param [Integer] mech Mechanism
|
131
|
+
# @return [PKCS11::CStruct] appropriate class as parameter for the mechanism
|
132
|
+
def vendor_mechanism_parameter_struct(mech)
|
133
|
+
Helper::MechanismParameters[mech]
|
134
|
+
end
|
135
|
+
|
136
|
+
private :unwrapped_initialize
|
137
|
+
private :unwrapped_C_GetSlotList
|
138
|
+
private :unwrapped_C_GetInfo
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'pkcs11/helper'
|
2
|
+
|
3
|
+
module PKCS11
|
4
|
+
# Cryptoki's logical view of a token is a device that stores objects and can perform
|
5
|
+
# cryptographic functions. Cryptoki defines three classes of object: data, certificates, and
|
6
|
+
# keys.
|
7
|
+
#
|
8
|
+
# Attributes are characteristics that distinguish an instance of an object.
|
9
|
+
class Object
|
10
|
+
include Helper
|
11
|
+
|
12
|
+
# @private
|
13
|
+
def initialize(pkcs11, session, object) # :nodoc:
|
14
|
+
@pk, @sess, @obj = pkcs11, session, object
|
15
|
+
end
|
16
|
+
|
17
|
+
# The object handle.
|
18
|
+
# @return [Integer]
|
19
|
+
def to_int
|
20
|
+
@obj
|
21
|
+
end
|
22
|
+
alias to_i to_int
|
23
|
+
|
24
|
+
# @private
|
25
|
+
def inspect # :nodoc:
|
26
|
+
"#<#{self.class} #{@obj.inspect}>"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get the value of one or several attributes of the object.
|
30
|
+
#
|
31
|
+
# @param [String, Symbol, Integer, Array] attribute can be String or Symbol
|
32
|
+
# of the attribute(s) constant or the attribute(s) number as Integer.
|
33
|
+
#
|
34
|
+
# @return [String, Integer, Boolean, Array, nil] the attribute value as String,
|
35
|
+
# Integer or true/false depending on the attribute type.
|
36
|
+
# If called with more than one parameter or with an Array, a Array
|
37
|
+
# of attribute values is returned.
|
38
|
+
# Unknown attributes (out of PKCS#11 v2.2) are not converted to adequate
|
39
|
+
# ruby objects but returned as String.
|
40
|
+
# That is true/false will be returned as "\\001" respectively "\\000".
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# object[:VALUE] # => "\000\000\000\000\000\000\000\000"
|
44
|
+
# object[:MODULUS_BITS] # => 768
|
45
|
+
# object[:MODULUS_BITS, :LABEL] # => [1024, "MyKey"]
|
46
|
+
#
|
47
|
+
# See PKCS#11 for attribute definitions.
|
48
|
+
def [](*attributes)
|
49
|
+
attrs = C_GetAttributeValue( attributes.flatten )
|
50
|
+
if attrs.length>1 || attributes.first.kind_of?(Array)
|
51
|
+
attrs.map(&:value)
|
52
|
+
else
|
53
|
+
attrs.first.value unless attrs.empty?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Modifies the value of one or several attributes of the object.
|
58
|
+
#
|
59
|
+
# @param [String, Symbol, Integer] attribute can be String or Symbol of the attribute constant
|
60
|
+
# or the attribute value as Integer.
|
61
|
+
# @param [String, Integer, Boolean, Array, nil] value value(s) the attribute(s) will be set to.
|
62
|
+
#
|
63
|
+
# Following value conversations are done from Ruby to C:
|
64
|
+
# true -> 0x01
|
65
|
+
# false -> 0x00
|
66
|
+
# nil -> NULL pointer
|
67
|
+
# Fixnum -> binary encoded unsigned long
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# object[:VALUE] = "\000\000\000\000\000\000\000\000"
|
71
|
+
# object[:MODULUS_BITS] = 768
|
72
|
+
# object[:MODULUS_BITS, :LABEL] = 1024, 'MyKey'
|
73
|
+
#
|
74
|
+
# See PKCS#11 for attribute definitions.
|
75
|
+
# @return value
|
76
|
+
def []=(*attributes)
|
77
|
+
values = attributes.pop
|
78
|
+
values = [values] unless values.kind_of?(Array)
|
79
|
+
raise ArgumentError, "different number of attributes to set (#{attributes.length}) and given values (#{values.length})" unless attributes.length == values.length
|
80
|
+
map = values.each.with_index.inject({}){|s, v| s[attributes[v[1]]] = v[0]; s }
|
81
|
+
C_SetAttributeValue( map )
|
82
|
+
end
|
83
|
+
|
84
|
+
# Modifies the value of one or more attributes of the object in a single call.
|
85
|
+
#
|
86
|
+
# @example
|
87
|
+
# object.attributes = {:SUBJECT => cert_subject, PKCS11::CKA_VALUE => cert_data}
|
88
|
+
# @return template
|
89
|
+
def C_SetAttributeValue(template={})
|
90
|
+
@pk.C_SetAttributeValue(@sess, @obj, to_attributes(template))
|
91
|
+
template
|
92
|
+
end
|
93
|
+
alias attributes= C_SetAttributeValue
|
94
|
+
|
95
|
+
# Obtains the value of one or more attributes of the object in a single call.
|
96
|
+
#
|
97
|
+
# @param [Array<String, Symbol, Integer>, Hash, String, Integer] attribute attribute names
|
98
|
+
# whose values should be returned
|
99
|
+
#
|
100
|
+
# Without params all known attributes are tried to read from the Object.
|
101
|
+
# This is significant slower then naming the needed attributes and should
|
102
|
+
# be used for debug purposes only.
|
103
|
+
#
|
104
|
+
# @return [Array<PKCS11::CK_ATTRIBUTE>] Requested attributes with values.
|
105
|
+
#
|
106
|
+
# @example
|
107
|
+
# certificate.attributes :VALUE, :CLASS
|
108
|
+
# => [#<PKCS11::CK_ATTRIBUTE CKA_VALUE (17) value="0\x82...">, #<PKCS11::CK_ATTRIBUTE CKA_CLASS (0) value=1>]
|
109
|
+
def C_GetAttributeValue(*template)
|
110
|
+
case template.length
|
111
|
+
when 0
|
112
|
+
return @pk.vendor_all_attribute_names.map{|attr|
|
113
|
+
begin
|
114
|
+
attributes(@pk.vendor_const_get(attr))
|
115
|
+
rescue PKCS11::Error
|
116
|
+
end
|
117
|
+
}.flatten.compact
|
118
|
+
when 1
|
119
|
+
template = template[0]
|
120
|
+
end
|
121
|
+
template = to_attributes template
|
122
|
+
@pk.C_GetAttributeValue(@sess, @obj, template)
|
123
|
+
end
|
124
|
+
alias attributes C_GetAttributeValue
|
125
|
+
|
126
|
+
# Copies an object, creating a new object for the copy.
|
127
|
+
#
|
128
|
+
# @param [Hash] template
|
129
|
+
#
|
130
|
+
# The template may specify new values for any attributes of the object that can ordinarily
|
131
|
+
# be modified (e.g., in the course of copying a secret key, a key's CKA_EXTRACTABLE
|
132
|
+
# attribute may be changed from true to false, but not the other way around.
|
133
|
+
# If this change is made, the new key's CKA_NEVER_EXTRACTABLE attribute will
|
134
|
+
# have the value false. Similarly, the template may specify that the new key's
|
135
|
+
# CKA_SENSITIVE attribute be true; the new key will have the same value for its
|
136
|
+
# CKA_ALWAYS_SENSITIVE attribute as the original key). It may also specify new
|
137
|
+
# values of the CKA_TOKEN and CKA_PRIVATE attributes (e.g., to copy a session
|
138
|
+
# object to a token object). If the template specifies a value of an attribute which is
|
139
|
+
# incompatible with other existing attributes of the object, the call fails with exception
|
140
|
+
# CKR_TEMPLATE_INCONSISTENT.
|
141
|
+
#
|
142
|
+
# Only session objects can be created during a read-only session. Only public objects can
|
143
|
+
# be created unless the normal user is logged in.
|
144
|
+
#
|
145
|
+
# @return [PKCS11::Object] the newly created object
|
146
|
+
def C_CopyObject(template={})
|
147
|
+
handle = @pk.C_CopyObject(@sess, @obj, to_attributes(template))
|
148
|
+
Object.new @pk, @sess, handle
|
149
|
+
end
|
150
|
+
alias copy C_CopyObject
|
151
|
+
|
152
|
+
# Destroys the object.
|
153
|
+
#
|
154
|
+
# Only session objects can be destroyed during a read-only session. Only public objects
|
155
|
+
# can be destroyed unless the normal user is logged in.
|
156
|
+
# @return [PKCS11::Object]
|
157
|
+
def C_DestroyObject()
|
158
|
+
@pk.C_DestroyObject(@sess, @obj)
|
159
|
+
self
|
160
|
+
end
|
161
|
+
alias destroy C_DestroyObject
|
162
|
+
|
163
|
+
# Gets the size of an object in bytes.
|
164
|
+
# @return [Integer]
|
165
|
+
def C_GetObjectSize()
|
166
|
+
@pk.C_GetObjectSize(@sess, @obj)
|
167
|
+
end
|
168
|
+
alias size C_GetObjectSize
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|