ruby-keychain 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4efbc44b1070dee58c312948985249d799d84278
4
- data.tar.gz: aafa371eab422c0fea83c4b878722937ee4fd7d5
3
+ metadata.gz: 7c2ee5b2ee12fb40fcc21b22df81639cb35104bf
4
+ data.tar.gz: c0863f638b7b25276ea88dfabe29ed20be92b72f
5
5
  SHA512:
6
- metadata.gz: 046246e35a3c27d9545caad0ee3c2287a4b7eb2c6b88b5c796ec971d603a896bebaeee3fd32a02503c1ade4c893e46f522f69e32a00fb59d5e3e75cd1bb102b5
7
- data.tar.gz: a1a7c7d7495792d9d1163b70093e2a968bfb1ae6a19f91ffd563cfce926746279859bd5c7aad3814e26c3bcb71734339df0802ebfc106ab193dc92af426d1894
6
+ metadata.gz: 2096c6908718c18c3cb741305e75141519a94f49c3439a98ceee5e780713fff9f684e8ee9962e670953eb848c8a28bfa5bcbe73ce7754d0dd679a96c91b3d6b7
7
+ data.tar.gz: 3b8f5d1789f5183ce0abac2cdad770b92f8b21ccf01998ce8dba185700e183e1f935053e11a4bae75a60e8541f5fec682f97bcfc8018f21a942bd51d74a30a90
@@ -1,3 +1,5 @@
1
- class Keychain::Access < Sec::Base
2
- register_type 'SecAccess'
1
+ module Keychain
2
+ class Access < Sec::Base
3
+ register_type 'SecAccess'
4
+ end
3
5
  end
@@ -15,43 +15,45 @@ module Sec
15
15
  attach_variable 'kSecAttrPublicKeyHash', :pointer
16
16
  end
17
17
 
18
- class Keychain::Certificate < Sec::Base
19
- register_type 'SecCertificate'
20
-
21
- ATTR_MAP = {CF::Base.typecast(Sec::kSecAttrAccessGroup) => :access_group,
22
- CF::Base.typecast(Sec::kSecAttrCertificateType) => :certificate_type,
23
- CF::Base.typecast(Sec::kSecAttrCertificateEncoding) => :certificate_encoding,
24
- CF::Base.typecast(Sec::kSecAttrLabel) => :label,
25
- CF::Base.typecast(Sec::kSecAttrSubject) => :subject,
26
- CF::Base.typecast(Sec::kSecAttrIssuer) => :issuer,
27
- CF::Base.typecast(Sec::kSecAttrSerialNumber) => :serial_number,
28
- CF::Base.typecast(Sec::kSecAttrSubjectKeyID) => :subject_key_id,
29
- CF::Base.typecast(Sec::kSecAttrPublicKeyHash) => :public_key_hash}
30
-
31
- ATTR_MAP[CF::Base.typecast(Sec::kSecAttrAccessible)] = :accessible if defined?(Sec::kSecAttrAccessible)
32
- ATTR_MAP[CF::Base.typecast(Sec::kSecAttrAccessControl)] = :access_control if defined?(Sec::kSecAttrAccessControl)
33
-
34
- INVERSE_ATTR_MAP = ATTR_MAP.invert
35
- define_attributes(ATTR_MAP)
36
-
37
- def klass
38
- Sec::Classes::CERTIFICATE.to_ruby
18
+ module Keychain
19
+ class Certificate < Sec::Base
20
+ register_type 'SecCertificate'
21
+
22
+ ATTR_MAP = {CF::Base.typecast(Sec::kSecAttrAccessGroup) => :access_group,
23
+ CF::Base.typecast(Sec::kSecAttrCertificateType) => :certificate_type,
24
+ CF::Base.typecast(Sec::kSecAttrCertificateEncoding) => :certificate_encoding,
25
+ CF::Base.typecast(Sec::kSecAttrLabel) => :label,
26
+ CF::Base.typecast(Sec::kSecAttrSubject) => :subject,
27
+ CF::Base.typecast(Sec::kSecAttrIssuer) => :issuer,
28
+ CF::Base.typecast(Sec::kSecAttrSerialNumber) => :serial_number,
29
+ CF::Base.typecast(Sec::kSecAttrSubjectKeyID) => :subject_key_id,
30
+ CF::Base.typecast(Sec::kSecAttrPublicKeyHash) => :public_key_hash}
31
+
32
+ ATTR_MAP[CF::Base.typecast(Sec::kSecAttrAccessible)] = :accessible if defined?(Sec::kSecAttrAccessible)
33
+ ATTR_MAP[CF::Base.typecast(Sec::kSecAttrAccessControl)] = :access_control if defined?(Sec::kSecAttrAccessControl)
34
+
35
+ INVERSE_ATTR_MAP = ATTR_MAP.invert
36
+ define_attributes(ATTR_MAP)
37
+
38
+ def klass
39
+ Sec::Classes::CERTIFICATE.to_ruby
40
+ end
41
+
42
+ def public_key
43
+ key_ref = FFI::MemoryPointer.new(:pointer)
44
+ status = Sec.SecCertificateCopyPublicKey(self, key_ref)
45
+ Sec.check_osstatus(status)
46
+
47
+ Key.new(key_ref.read_pointer).release_on_gc
48
+ end
49
+
50
+ def x509
51
+ data_ptr = Sec.SecCertificateCopyData(self)
52
+ data = CF::Data.new(data_ptr)
53
+
54
+ result = OpenSSL::X509::Certificate.new(data.to_s)
55
+ data.release
56
+ result
57
+ end
39
58
  end
40
-
41
- def public_key
42
- key_ref = FFI::MemoryPointer.new(:pointer)
43
- status = Sec.SecCertificateCopyPublicKey(self, key_ref)
44
- Sec.check_osstatus(status)
45
-
46
- Keychain::Key.new(key_ref.read_pointer).release_on_gc
47
- end
48
-
49
- def x509
50
- data_ptr = Sec.SecCertificateCopyData(self)
51
- data = CF::Data.new(data_ptr)
52
-
53
- result = OpenSSL::X509::Certificate.new(data.to_s)
54
- data.release
55
- result
56
- end
57
- end
59
+ end
@@ -6,16 +6,18 @@ end
6
6
  # The base class of all keychain related errors
7
7
  #
8
8
  # The original error code is available as `code`
9
- class Keychain::Error < StandardError
10
- attr_accessor :code
11
- def initialize(code)
12
- self.code = code
13
- description = Sec.SecCopyErrorMessageString(code, nil)
14
- if description.null?
15
- super("Sec Error #{code}")
16
- else
17
- description = CF::Base.typecast(description)
18
- super("#{description.to_s} (#{code})")
9
+ module Keychain
10
+ class Error < StandardError
11
+ attr_accessor :code
12
+ def initialize(code)
13
+ self.code = code
14
+ description = Sec.SecCopyErrorMessageString(code, nil)
15
+ if description.null?
16
+ super("Sec Error #{code}")
17
+ else
18
+ description = CF::Base.typecast(description)
19
+ super("#{description.to_s} (#{code})")
20
+ end
19
21
  end
20
22
  end
21
23
  end
@@ -8,46 +8,48 @@ module Sec
8
8
  attach_variable 'kSecAttrLabel', :pointer
9
9
  end
10
10
 
11
- class Keychain::Identity < Sec::Base
12
- register_type 'SecIdentity'
11
+ module Keychain
12
+ class Identity < Sec::Base
13
+ register_type 'SecIdentity'
13
14
 
14
- ATTR_MAP = Keychain::Certificate::ATTR_MAP.merge(Keychain::Key::ATTR_MAP)
15
+ ATTR_MAP = Certificate::ATTR_MAP.merge(Key::ATTR_MAP)
15
16
 
16
- INVERSE_ATTR_MAP = ATTR_MAP.invert
17
- define_attributes(ATTR_MAP)
17
+ INVERSE_ATTR_MAP = ATTR_MAP.invert
18
+ define_attributes(ATTR_MAP)
18
19
 
19
- def klass
20
- Sec::Classes::IDENTITY.to_ruby
21
- end
20
+ def klass
21
+ Sec::Classes::IDENTITY.to_ruby
22
+ end
22
23
 
23
- def certificate
24
- certificate_ref = FFI::MemoryPointer.new(:pointer)
25
- status = Sec.SecIdentityCopyCertificate(self, certificate_ref)
26
- Sec.check_osstatus(status)
24
+ def certificate
25
+ certificate_ref = FFI::MemoryPointer.new(:pointer)
26
+ status = Sec.SecIdentityCopyCertificate(self, certificate_ref)
27
+ Sec.check_osstatus(status)
27
28
 
28
- Keychain::Certificate.new(certificate_ref.read_pointer).release_on_gc
29
- end
29
+ Certificate.new(certificate_ref.read_pointer).release_on_gc
30
+ end
30
31
 
31
- def private_key
32
- key_ref = FFI::MemoryPointer.new(:pointer)
33
- status = Sec.SecIdentityCopyPrivateKey(self, key_ref)
34
- Sec.check_osstatus(status)
32
+ def private_key
33
+ key_ref = FFI::MemoryPointer.new(:pointer)
34
+ status = Sec.SecIdentityCopyPrivateKey(self, key_ref)
35
+ Sec.check_osstatus(status)
35
36
 
36
- Keychain::Key.new(key_ref.read_pointer).release_on_gc
37
- end
37
+ Key.new(key_ref.read_pointer).release_on_gc
38
+ end
38
39
 
39
- def pkcs12(passphrase='')
40
- flags = Sec::SecItemImportExportKeyParameters.new
41
- flags[:version] = Sec::SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION
42
- flags[:passphrase] = CF::String.from_string(passphrase).to_ptr
40
+ def pkcs12(passphrase='')
41
+ flags = Sec::SecItemImportExportKeyParameters.new
42
+ flags[:version] = Sec::SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION
43
+ flags[:passphrase] = CF::String.from_string(passphrase).to_ptr
43
44
 
44
- data_ptr = FFI::MemoryPointer.new(:pointer)
45
- status = Sec.SecItemExport(self, :kSecFormatPKCS12, 0, flags, data_ptr)
46
- Sec.check_osstatus(status)
45
+ data_ptr = FFI::MemoryPointer.new(:pointer)
46
+ status = Sec.SecItemExport(self, :kSecFormatPKCS12, 0, flags, data_ptr)
47
+ Sec.check_osstatus(status)
47
48
 
48
- data = CF::Data.new(data_ptr.read_pointer)
49
- result = OpenSSL::PKCS12.new(data.to_s)
50
- data.release
51
- result
49
+ data = CF::Data.new(data_ptr.read_pointer)
50
+ result = OpenSSL::PKCS12.new(data.to_s)
51
+ data.release
52
+ result
53
+ end
52
54
  end
53
- end
55
+ end
@@ -9,166 +9,168 @@ end
9
9
  # An individual item from the keychain. Individual accessors are generated for the items attributes
10
10
  #
11
11
  #
12
- class Keychain::Item < Sec::Base
13
- register_type 'SecKeychainItem'
14
-
15
- ATTR_MAP = {CF::Base.typecast(Sec::kSecAttrAccess) => :access,
16
- CF::Base.typecast(Sec::kSecAttrAccount) => :account,
17
- CF::Base.typecast(Sec::kSecAttrAuthenticationType) => :authentication_type,
18
- CF::Base.typecast(Sec::kSecAttrComment) => :comment,
19
- CF::Base.typecast(Sec::kSecAttrCreationDate) => :created_at,
20
- CF::Base.typecast(Sec::kSecAttrCreator) => :creator,
21
- CF::Base.typecast(Sec::kSecAttrDescription) => :description,
22
- CF::Base.typecast(Sec::kSecAttrGeneric) => :generic,
23
- CF::Base.typecast(Sec::kSecAttrIsInvisible) => :invisible,
24
- CF::Base.typecast(Sec::kSecAttrIsNegative) => :negative,
25
- CF::Base.typecast(Sec::kSecAttrLabel) => :label,
26
- CF::Base.typecast(Sec::kSecAttrModificationDate) => :updated_at,
27
- CF::Base.typecast(Sec::kSecAttrPath) => :path,
28
- CF::Base.typecast(Sec::kSecAttrPort) => :port,
29
- CF::Base.typecast(Sec::kSecAttrProtocol) => :protocol,
30
- CF::Base.typecast(Sec::kSecAttrSecurityDomain) => :security_domain,
31
- CF::Base.typecast(Sec::kSecAttrServer) => :server,
32
- CF::Base.typecast(Sec::kSecAttrService) => :service,
33
- CF::Base.typecast(Sec::kSecAttrType) => :type,
34
- CF::Base.typecast(Sec::kSecClass) => :klass}
35
-
36
- INVERSE_ATTR_MAP = ATTR_MAP.invert
37
- define_attributes(ATTR_MAP)
38
-
39
- # returns a programmer friendly description of the item
40
- # @return [String]
41
- def inspect
42
- "<SecKeychainItem 0x#{@ptr.address.to_s(16)} #{service ? "service: #{service}" : "server: #{server}"} account: #{account}>"
43
- end
12
+ module Keychain
13
+ class Item < Sec::Base
14
+ register_type 'SecKeychainItem'
15
+
16
+ ATTR_MAP = {CF::Base.typecast(Sec::kSecAttrAccess) => :access,
17
+ CF::Base.typecast(Sec::kSecAttrAccount) => :account,
18
+ CF::Base.typecast(Sec::kSecAttrAuthenticationType) => :authentication_type,
19
+ CF::Base.typecast(Sec::kSecAttrComment) => :comment,
20
+ CF::Base.typecast(Sec::kSecAttrCreationDate) => :created_at,
21
+ CF::Base.typecast(Sec::kSecAttrCreator) => :creator,
22
+ CF::Base.typecast(Sec::kSecAttrDescription) => :description,
23
+ CF::Base.typecast(Sec::kSecAttrGeneric) => :generic,
24
+ CF::Base.typecast(Sec::kSecAttrIsInvisible) => :invisible,
25
+ CF::Base.typecast(Sec::kSecAttrIsNegative) => :negative,
26
+ CF::Base.typecast(Sec::kSecAttrLabel) => :label,
27
+ CF::Base.typecast(Sec::kSecAttrModificationDate) => :updated_at,
28
+ CF::Base.typecast(Sec::kSecAttrPath) => :path,
29
+ CF::Base.typecast(Sec::kSecAttrPort) => :port,
30
+ CF::Base.typecast(Sec::kSecAttrProtocol) => :protocol,
31
+ CF::Base.typecast(Sec::kSecAttrSecurityDomain) => :security_domain,
32
+ CF::Base.typecast(Sec::kSecAttrServer) => :server,
33
+ CF::Base.typecast(Sec::kSecAttrService) => :service,
34
+ CF::Base.typecast(Sec::kSecAttrType) => :type,
35
+ CF::Base.typecast(Sec::kSecClass) => :klass}
36
+
37
+ INVERSE_ATTR_MAP = ATTR_MAP.invert
38
+ define_attributes(ATTR_MAP)
39
+
40
+ # returns a programmer friendly description of the item
41
+ # @return [String]
42
+ def inspect
43
+ "<SecKeychainItem 0x#{@ptr.address.to_s(16)} #{service ? "service: #{service}" : "server: #{server}"} account: #{account}>"
44
+ end
44
45
 
45
- # Creates a new keychain item either from an FFI::Pointer or a hash of attributes
46
- #
47
- # @param [FFI::Pointer, Hash] attrs_or_pointer Either an FFI::Pointer to an existing
48
- # SecKeychainItemRef to wrap or hash of attributes to create a new, unsaved Keychain::Item from
49
- # see {Keychain::Scope#create}
50
- #
51
- def self.new(attrs_or_pointer)
52
- if attrs_or_pointer.is_a? Hash
53
- super(0).tap do |result|
54
- attrs_or_pointer.each {|k,v| result.send("#{k}=", v)}
46
+ # Creates a new keychain item either from an FFI::Pointer or a hash of attributes
47
+ #
48
+ # @param [FFI::Pointer, Hash] attrs_or_pointer Either an FFI::Pointer to an existing
49
+ # SecKeychainItemRef to wrap or hash of attributes to create a new, unsaved Keychain::Item from
50
+ # see {Keychain::Scope#create}
51
+ #
52
+ def self.new(attrs_or_pointer)
53
+ if attrs_or_pointer.is_a? Hash
54
+ super(0).tap do |result|
55
+ attrs_or_pointer.each {|k,v| result.send("#{k}=", v)}
56
+ end
57
+ else
58
+ super
55
59
  end
56
- else
57
- super
58
60
  end
59
- end
60
61
 
61
- # Removes the item from the associated keychain
62
- #
63
- def delete
64
- status = Sec.SecKeychainItemDelete(self)
65
- Sec.check_osstatus(status)
66
- self
67
- end
62
+ # Removes the item from the associated keychain
63
+ #
64
+ def delete
65
+ status = Sec.SecKeychainItemDelete(self)
66
+ Sec.check_osstatus(status)
67
+ self
68
+ end
68
69
 
69
- # Set a new password for the item
70
- # @note The new password is not saved into the keychain until you call {Keychain::Item#save!}
71
- # @param [String] value The new value for the password
72
- # @return [String] The set value
73
- def password=(value)
74
- @unsaved_password = value
75
- end
70
+ # Set a new password for the item
71
+ # @note The new password is not saved into the keychain until you call {Keychain::Item#save!}
72
+ # @param [String] value The new value for the password
73
+ # @return [String] The set value
74
+ def password=(value)
75
+ @unsaved_password = value
76
+ end
76
77
 
77
- # Fetches the password data associated with the item. This may cause the user to be asked for access
78
- # @return [String] The password data, an ASCII_8BIT encoded string
79
- def password
80
- return @unsaved_password if @unsaved_password
81
- out_buffer = FFI::MemoryPointer.new(:pointer)
82
- status = Sec.SecItemCopyMatching({Sec::Query::ITEM_LIST => CF::Array.immutable([self]),
83
- Sec::Query::SEARCH_LIST => [self.keychain],
84
- Sec::Query::CLASS => self.klass,
85
- Sec::Query::RETURN_DATA => true}.to_cf, out_buffer)
86
- Sec.check_osstatus(status)
87
- CF::Base.typecast(out_buffer.read_pointer).release_on_gc.to_s
88
- end
78
+ # Fetches the password data associated with the item. This may cause the user to be asked for access
79
+ # @return [String] The password data, an ASCII_8BIT encoded string
80
+ def password
81
+ return @unsaved_password if @unsaved_password
82
+ out_buffer = FFI::MemoryPointer.new(:pointer)
83
+ status = Sec.SecItemCopyMatching({Sec::Query::ITEM_LIST => CF::Array.immutable([self]),
84
+ Sec::Query::SEARCH_LIST => [self.keychain],
85
+ Sec::Query::CLASS => self.klass,
86
+ Sec::Query::RETURN_DATA => true}.to_cf, out_buffer)
87
+ Sec.check_osstatus(status)
88
+ CF::Base.typecast(out_buffer.read_pointer).release_on_gc.to_s
89
+ end
89
90
 
90
- # Attempts to update the keychain with any changes made to the item
91
- # or saves a previously unpersisted item
92
- # @param [optional, Hash] options extra options when saving the item
93
- # @option options [Keychain::Keychain] :keychain when saving an unsaved item, they keychain to save it in
94
- # @return [Keychain::Item] returns the item
95
- def save!(options={})
96
- if persisted?
97
- cf_dict = update
98
- else
99
- cf_dict = create(options)
100
- self.ptr = cf_dict[Sec::Value::REF].to_ptr
101
- self.retain.release_on_gc
91
+ # Attempts to update the keychain with any changes made to the item
92
+ # or saves a previously unpersisted item
93
+ # @param [optional, Hash] options extra options when saving the item
94
+ # @option options [Keychain::Keychain] :keychain when saving an unsaved item, they keychain to save it in
95
+ # @return [Keychain::Item] returns the item
96
+ def save!(options={})
97
+ if persisted?
98
+ cf_dict = update
99
+ else
100
+ cf_dict = create(options)
101
+ self.ptr = cf_dict[Sec::Value::REF].to_ptr
102
+ self.retain.release_on_gc
103
+ end
104
+ @unsaved_password = nil
105
+ update_self_from_dictionary(cf_dict)
106
+ cf_dict.release
107
+ self
102
108
  end
103
- @unsaved_password = nil
104
- update_self_from_dictionary(cf_dict)
105
- cf_dict.release
106
- self
107
- end
108
109
 
109
- # @private
110
- def self.from_dictionary_of_attributes(cf_dict)
111
- new(0).tap {|item| item.send :update_self_from_dictionary, cf_dict}
112
- end
110
+ # @private
111
+ def self.from_dictionary_of_attributes(cf_dict)
112
+ new(0).tap {|item| item.send :update_self_from_dictionary, cf_dict}
113
+ end
113
114
 
114
- # Whether the item has been persisted to the keychain
115
- # @return [Boolean]
116
- def persisted?
117
- !@ptr.null?
118
- end
115
+ # Whether the item has been persisted to the keychain
116
+ # @return [Boolean]
117
+ def persisted?
118
+ !@ptr.null?
119
+ end
119
120
 
120
- private
121
+ private
121
122
 
122
- def create(options)
123
- result = FFI::MemoryPointer.new :pointer
124
- query = build_create_query(options)
125
- query.merge!(build_new_attributes)
126
- status = Sec.SecItemAdd(query, result);
127
- Sec.check_osstatus(status)
128
- cf_dict = CF::Base.typecast(result.read_pointer)
129
- end
123
+ def create(options)
124
+ result = FFI::MemoryPointer.new :pointer
125
+ query = build_create_query(options)
126
+ query.merge!(build_new_attributes)
127
+ status = Sec.SecItemAdd(query, result);
128
+ Sec.check_osstatus(status)
129
+ cf_dict = CF::Base.typecast(result.read_pointer)
130
+ end
130
131
 
131
- def update
132
- status = Sec.SecItemUpdate({Sec::Query::SEARCH_LIST => [self.keychain],
133
- Sec::Query::ITEM_LIST => [self],
134
- Sec::Query::CLASS => klass}.to_cf, build_new_attributes);
135
- Sec.check_osstatus(status)
136
-
137
- result = FFI::MemoryPointer.new :pointer
138
- query = build_refresh_query
139
- status = Sec.SecItemCopyMatching(query, result);
140
- Sec.check_osstatus(status)
141
- cf_dict = CF::Base.typecast(result.read_pointer)
142
- end
143
-
144
- def build_create_query options
145
- query = CF::Dictionary.mutable
146
- query[Sec::Value::DATA] = CF::Data.from_string(@unsaved_password) if @unsaved_password
147
- query[Sec::Query::KEYCHAIN] = options[:keychain] if options[:keychain]
148
- query[Sec::Query::RETURN_ATTRIBUTES] = CF::Boolean::TRUE
149
- query[Sec::Query::RETURN_REF] = CF::Boolean::TRUE
150
- query
151
- end
132
+ def update
133
+ status = Sec.SecItemUpdate({Sec::Query::SEARCH_LIST => [self.keychain],
134
+ Sec::Query::ITEM_LIST => [self],
135
+ Sec::Query::CLASS => klass}.to_cf, build_new_attributes);
136
+ Sec.check_osstatus(status)
137
+
138
+ result = FFI::MemoryPointer.new :pointer
139
+ query = build_refresh_query
140
+ status = Sec.SecItemCopyMatching(query, result);
141
+ Sec.check_osstatus(status)
142
+ cf_dict = CF::Base.typecast(result.read_pointer)
143
+ end
144
+
145
+ def build_create_query options
146
+ query = CF::Dictionary.mutable
147
+ query[Sec::Value::DATA] = CF::Data.from_string(@unsaved_password) if @unsaved_password
148
+ query[Sec::Query::KEYCHAIN] = options[:keychain] if options[:keychain]
149
+ query[Sec::Query::RETURN_ATTRIBUTES] = CF::Boolean::TRUE
150
+ query[Sec::Query::RETURN_REF] = CF::Boolean::TRUE
151
+ query
152
+ end
152
153
 
153
- def build_refresh_query
154
- query = CF::Dictionary.mutable
155
- query[Sec::Query::SEARCH_LIST] = CF::Array.immutable([self.keychain])
156
- query[Sec::Query::ITEM_LIST] = CF::Array.immutable([self])
157
- query[Sec::Query::RETURN_ATTRIBUTES] = CF::Boolean::TRUE
158
- query[Sec::Query::RETURN_REF] = CF::Boolean::TRUE
159
- query[Sec::Query::CLASS] = klass.to_cf
160
- query
161
- end
154
+ def build_refresh_query
155
+ query = CF::Dictionary.mutable
156
+ query[Sec::Query::SEARCH_LIST] = CF::Array.immutable([self.keychain])
157
+ query[Sec::Query::ITEM_LIST] = CF::Array.immutable([self])
158
+ query[Sec::Query::RETURN_ATTRIBUTES] = CF::Boolean::TRUE
159
+ query[Sec::Query::RETURN_REF] = CF::Boolean::TRUE
160
+ query[Sec::Query::CLASS] = klass.to_cf
161
+ query
162
+ end
162
163
 
163
- def build_new_attributes
164
- new_attributes = CF::Dictionary.mutable
165
- @attributes.each do |k,v|
166
- next if k == :created_at || k == :updated_at
167
- next if k == :klass && persisted?
168
- k = self.class::INVERSE_ATTR_MAP[k]
169
- new_attributes[k] = v.to_cf
164
+ def build_new_attributes
165
+ new_attributes = CF::Dictionary.mutable
166
+ @attributes.each do |k,v|
167
+ next if k == :created_at || k == :updated_at
168
+ next if k == :klass && persisted?
169
+ k = self.class::INVERSE_ATTR_MAP[k]
170
+ new_attributes[k] = v.to_cf
171
+ end
172
+ new_attributes[Sec::Value::DATA] = CF::Data.from_string(@unsaved_password) if @unsaved_password
173
+ new_attributes
170
174
  end
171
- new_attributes[Sec::Value::DATA] = CF::Data.from_string(@unsaved_password) if @unsaved_password
172
- new_attributes
173
175
  end
174
176
  end
@@ -67,48 +67,50 @@ module Sec
67
67
 
68
68
  end
69
69
 
70
- class Keychain::Key < Sec::Base
71
- register_type 'SecKey'
72
-
73
- ATTR_MAP = {CF::Base.typecast(Sec::kSecAttrAccessGroup) => :access_group,
74
- CF::Base.typecast(Sec::kSecAttrKeyClass) => :key_class,
75
- CF::Base.typecast(Sec::kSecAttrLabel) => :label,
76
- CF::Base.typecast(Sec::kSecAttrApplicationLabel) => :application_label,
77
- CF::Base.typecast(Sec::kSecAttrIsPermanent) => :is_permanent,
78
- CF::Base.typecast(Sec::kSecAttrApplicationTag) => :application_tag,
79
- CF::Base.typecast(Sec::kSecAttrKeyType) => :key_type,
80
- CF::Base.typecast(Sec::kSecAttrKeySizeInBits) => :size_in_bites,
81
- CF::Base.typecast(Sec::kSecAttrEffectiveKeySize) => :effective_key_size,
82
- CF::Base.typecast(Sec::kSecAttrCanEncrypt) => :can_encrypt,
83
- CF::Base.typecast(Sec::kSecAttrCanDecrypt) => :can_decrypt,
84
- CF::Base.typecast(Sec::kSecAttrCanDerive) => :can_derive,
85
- CF::Base.typecast(Sec::kSecAttrCanSign) => :can_sign,
86
- CF::Base.typecast(Sec::kSecAttrCanVerify) => :can_verify,
87
- CF::Base.typecast(Sec::kSecAttrCanWrap) => :can_wrap,
88
- CF::Base.typecast(Sec::kSecAttrCanUnwrap) => :can_unwrap}
89
-
90
- ATTR_MAP[CF::Base.typecast(Sec::kSecAttrAccessible)] = :accessible if defined?(Sec::kSecAttrAccessible)
91
- ATTR_MAP[CF::Base.typecast(Sec::kSecAttrAccessControl)] = :access_control if defined?(Sec::kSecAttrAccessControl)
92
-
93
- INVERSE_ATTR_MAP = ATTR_MAP.invert
94
- define_attributes(ATTR_MAP)
95
-
96
- def klass
97
- Sec::Classes::KEY.to_ruby
98
- end
99
-
100
- def export(passphrase = nil, format = :kSecFormatUnknown)
101
- flags = Sec::SecItemImportExportKeyParameters.new
102
- flags[:version] = Sec::SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION
103
- flags[:passphrase] = CF::String.from_string(passphrase).to_ptr if passphrase
104
-
105
- data_ptr = FFI::MemoryPointer.new(:pointer)
106
- status = Sec.SecItemExport(self, format, :kSecItemPemArmour, flags, data_ptr)
107
- Sec.check_osstatus(status)
108
-
109
- data = CF::Data.new(data_ptr.read_pointer)
110
- result = data.to_s
111
- data.release
112
- result
70
+ module Keychain
71
+ class Key < Sec::Base
72
+ register_type 'SecKey'
73
+
74
+ ATTR_MAP = {CF::Base.typecast(Sec::kSecAttrAccessGroup) => :access_group,
75
+ CF::Base.typecast(Sec::kSecAttrKeyClass) => :key_class,
76
+ CF::Base.typecast(Sec::kSecAttrLabel) => :label,
77
+ CF::Base.typecast(Sec::kSecAttrApplicationLabel) => :application_label,
78
+ CF::Base.typecast(Sec::kSecAttrIsPermanent) => :is_permanent,
79
+ CF::Base.typecast(Sec::kSecAttrApplicationTag) => :application_tag,
80
+ CF::Base.typecast(Sec::kSecAttrKeyType) => :key_type,
81
+ CF::Base.typecast(Sec::kSecAttrKeySizeInBits) => :size_in_bites,
82
+ CF::Base.typecast(Sec::kSecAttrEffectiveKeySize) => :effective_key_size,
83
+ CF::Base.typecast(Sec::kSecAttrCanEncrypt) => :can_encrypt,
84
+ CF::Base.typecast(Sec::kSecAttrCanDecrypt) => :can_decrypt,
85
+ CF::Base.typecast(Sec::kSecAttrCanDerive) => :can_derive,
86
+ CF::Base.typecast(Sec::kSecAttrCanSign) => :can_sign,
87
+ CF::Base.typecast(Sec::kSecAttrCanVerify) => :can_verify,
88
+ CF::Base.typecast(Sec::kSecAttrCanWrap) => :can_wrap,
89
+ CF::Base.typecast(Sec::kSecAttrCanUnwrap) => :can_unwrap}
90
+
91
+ ATTR_MAP[CF::Base.typecast(Sec::kSecAttrAccessible)] = :accessible if defined?(Sec::kSecAttrAccessible)
92
+ ATTR_MAP[CF::Base.typecast(Sec::kSecAttrAccessControl)] = :access_control if defined?(Sec::kSecAttrAccessControl)
93
+
94
+ INVERSE_ATTR_MAP = ATTR_MAP.invert
95
+ define_attributes(ATTR_MAP)
96
+
97
+ def klass
98
+ Sec::Classes::KEY.to_ruby
99
+ end
100
+
101
+ def export(passphrase = nil, format = :kSecFormatUnknown)
102
+ flags = Sec::SecItemImportExportKeyParameters.new
103
+ flags[:version] = Sec::SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION
104
+ flags[:passphrase] = CF::String.from_string(passphrase).to_ptr if passphrase
105
+
106
+ data_ptr = FFI::MemoryPointer.new(:pointer)
107
+ status = Sec.SecItemExport(self, format, :kSecItemPemArmour, flags, data_ptr)
108
+ Sec.check_osstatus(status)
109
+
110
+ data = CF::Data.new(data_ptr.read_pointer)
111
+ result = data.to_s
112
+ data.release
113
+ result
114
+ end
113
115
  end
114
116
  end
@@ -1,3 +1,5 @@
1
- class Keychain::TrustedApplication < Sec::Base
2
- register_type 'SecTrustedApplication'
1
+ module Keychain
2
+ class TrustedApplication < Sec::Base
3
+ register_type 'SecTrustedApplication'
4
+ end
3
5
  end
@@ -1,4 +1,4 @@
1
1
  module Keychain
2
2
  # The current version string
3
- VERSION = '0.3.1'
3
+ VERSION = '0.3.2'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-keychain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frederick Cheung