pkcs11 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Load the correct version if it's a Windows binary gem
4
- if RUBY_PLATFORM =~/(mswin|mingw)/i
5
- major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or
6
- raise "Oops, can't extract the major/minor version from #{RUBY_VERSION.dump}"
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'
@@ -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
- # Example usage:
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
- module InspectableStruct
30
- # Array of the InspectableStruct's attribute names.
31
- def members
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 the InspectableStruct's attribute names and values.
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 # :nodoc:
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
- module InspectableAttribute
48
- # Array of the InspectableStruct's attribute names.
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 of the InspectableStruct's attribute values.
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 the InspectableStruct's attribute names and values.
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
- # "#<#{self.class} #{ to_s ? "#{to_s} (#{@value})" : @value}>"
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
@@ -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:: Path to the *.so or *.dll file to load.
9
- # args:: A Hash or CK_C_INITIALIZE_ARGS instance with load params.
10
- def initialize(so_path, args={})
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. tokenPresent indicates
31
- # whether the list obtained includes only those slots with a token present (true), or
32
- # all slots (false);
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
- alias unwrapped_C_Finalize C_Finalize
52
- # Close and unload library. If not called, the library is freed by the GC.
53
- def C_Finalize
54
- unwrapped_C_Finalize
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
@@ -1,33 +1,47 @@
1
+ require 'pkcs11/helper'
2
+
1
3
  module PKCS11
2
- # Cryptokis logical view of a token is a device that stores objects and can perform
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
- # Returns the value of one attribute of the object.
29
+ # Get the value of one attribute of the object.
23
30
  #
24
- # attribute:: can be String or Symbol of the attribute constant
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
- # Returns the attribute value as String, Integer or true/false
28
- # depending on the attribute type.
29
- # Unknown attributes (out of PKCS#11 v2.2) are not converted but returned as String.
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:: can be String or Symbol of the attribute constant
52
+ # @param [String, Symbol, Integer] attribute can be String or Symbol of the attribute constant
39
53
  # or the attribute value as Integer.
40
- # value:: String value the attribute will be set to.
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
- # Examples:
75
+ # @example
54
76
  # object.attributes = {:SUBJECT => cert_subject, PKCS11::CKA_VALUE => cert_data}
77
+ # @return template
55
78
  def C_SetAttributeValue(template={})
56
- template = Session.hash_to_attributes template
57
- @pk.C_SetAttributeValue(@sess, @obj, template)
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
- # Returns an Array of PKCS11::CK_ATTRIBUTE's.
93
+ # @return [Array<PKCS11::CK_ATTRIBUTE>] Requested attributes with values.
68
94
  #
69
- # Example:
70
- # certificate.attributes :ID, :VALUE
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 = Session.hash_to_attributes 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