pkcs11 0.2.4-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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
|