Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
81f5861
The goal of this patch is to enable updating keys and certificates st…
Feb 17, 2017
315934f
Add support for querying certificate information. Add helper methods…
Jul 25, 2017
9515277
Add support for determining the type of key - public, private or symm…
Jul 25, 2017
21dcbba
Read attributes on demand and move delete method to the base class.
Jul 25, 2017
54d3762
Add helper methods for certificates and identities.
Jul 25, 2017
aa0c322
Separate out and expand access apis.
Jul 25, 2017
6d13b73
Merge branch 'master' into cfis
Jul 25, 2017
0bba4ff
Fix up local variable.
Jul 25, 2017
cbc5f2a
Fix creating ruby PKCS12 object.
Jul 26, 2017
33c83f6
Update to newer gem versions.
Jul 26, 2017
5a92aef
Allow any app to access certificate - helps in identity tests.
Jul 26, 2017
1414f70
Fix up tests.
Jul 26, 2017
49ca1c9
Go back to previous way of handling attributes.
Jul 26, 2017
9821085
Update item attribute based on latest Apple documentation.
Jul 26, 2017
76a547c
Add concept of updateable attributes versus hard coding them in updat…
Jul 26, 2017
cd3d6b6
Add support for scope/search match keys. Also centralize all search …
Aug 1, 2017
3aed287
Add a couple of missing attributes.
Aug 1, 2017
38bc125
Formatting.
Aug 1, 2017
4c8c5c4
Add helper method for querying certificates.
Aug 1, 2017
187c8c8
Add in needed require.
Aug 1, 2017
8652747
Add rake tasks for packaging gem.
Aug 1, 2017
1b48ace
Update dependencies and versions.
Aug 1, 2017
607933a
By default trust the application importing the keychain item.
Sep 25, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
require 'rubygems/package_task'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new('spec')

task :default => :spec
task :default => :spec

# Read the spec file
spec = Gem::Specification.load('keychain.gemspec')

# Setup gem package task
Gem::PackageTask.new(spec) do |pkg|
pkg.package_dir = 'pkg'
pkg.need_tar = false
end
11 changes: 5 additions & 6 deletions keychain.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ Gem::Specification.new do |s|
s.summary = %q{Ruby wrapper for OS X's keychain}
s.required_ruby_version = '>= 1.9.2'

s.add_runtime_dependency "ffi"
s.add_runtime_dependency "ffi", ">= 1.9.18"
s.add_runtime_dependency "corefoundation", "~>0.2.0"
s.add_development_dependency "rspec", '~> 3.3', '>= 3.3.0'
s.add_development_dependency "rake", '~> 10.4', '>= 10.4.2'
s.add_development_dependency "yard", '~> 0.8.7'
s.add_development_dependency "redcarpet", '~>3.2', '>= 3.2.3'

s.add_development_dependency "rspec", '>= 3.6.0'
s.add_development_dependency "rake", '>= 12.0.0'
s.add_development_dependency "yard", '>= 0.9.9'
s.add_development_dependency "redcarpet", '>= 3.4.0'
end

2 changes: 2 additions & 0 deletions lib/keychain.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require 'ffi'
require 'set'
require 'corefoundation'
require 'keychain/sec'
require 'keychain/access'
require 'keychain/acl'
require 'keychain/trusted_application'
require 'keychain/keychain'
require 'keychain/error'
Expand Down
44 changes: 44 additions & 0 deletions lib/keychain/access.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,49 @@
module Sec
attach_function 'SecAccessCreate', [:pointer, :pointer, :pointer], :osstatus
attach_function 'SecKeychainItemCopyAccess', [:pointer, :pointer], :osstatus
attach_function 'SecAccessCopyACLList', [:pointer, :pointer], :osstatus
attach_function 'SecAccessCopyMatchingACLList', [:pointer, :pointer], :pointer
attach_function 'SecKeychainItemSetAccess', [:pointer, :pointer], :osstatus
end

module Keychain
module AccessMixin
def access
access_buffer = FFI::MemoryPointer.new(:pointer)
status = Sec.SecKeychainItemCopyAccess(self, access_buffer)
Sec.check_osstatus status
Access.new(access_buffer.read_pointer)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need a release_on_gc here (to eventually release the result of SecKeychainItemCopyAccess?)

end

def access=(value)
status = Sec.SecKeychainItemSetAccess(self, value.to_cf)
Sec.check_osstatus status
end
end

class Access < Sec::Base
register_type 'SecAccess'

def self.create(description, trusted_apps = [])
access_buffer = FFI::MemoryPointer.new(:pointer)
status = Sec.SecAccessCreate(description.to_cf, trusted_apps.to_cf, access_buffer)
Sec.check_osstatus status
self.new(access_buffer.read_pointer)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here too?

end

def acls
acl_list_ref = FFI::MemoryPointer.new(:pointer)
status = Sec.SecAccessCopyACLList(self, acl_list_ref)
Sec.check_osstatus status
array_ref = CF::Base.typecast(acl_list_ref.read_pointer).release_on_gc
array_ref.to_ruby
end

def matching_acls(authorization_tag)
access_buffer = FFI::MemoryPointer.new(:pointer)
authorization_tag_cf = CF::Base.typecast(authorization_tag)
acl_list_ref = Sec.SecAccessCopyMatchingACLList(self, authorization_tag_cf)
acl_list_ref.null? ? Array.new : CF::Base.typecast(acl_list_ref)
end
end
end
74 changes: 74 additions & 0 deletions lib/keychain/acl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
module Sec
attach_function 'SecACLCopyContents', [:pointer, :pointer, :pointer, :pointer], :osstatus
attach_function 'SecACLRemove', [:pointer], :osstatus
attach_function 'SecACLCopyAuthorizations', [:pointer], :pointer
attach_function 'SecACLSetContents', [:pointer, :pointer, :pointer, :pointer], :osstatus
attach_variable 'kSecACLAuthorizationAny', :pointer
attach_variable 'kSecACLAuthorizationLogin', :pointer
attach_variable 'kSecACLAuthorizationGenKey', :pointer
attach_variable 'kSecACLAuthorizationDelete', :pointer
attach_variable 'kSecACLAuthorizationExportWrapped', :pointer
attach_variable 'kSecACLAuthorizationExportClear', :pointer
attach_variable 'kSecACLAuthorizationImportWrapped', :pointer
attach_variable 'kSecACLAuthorizationImportClear', :pointer
attach_variable 'kSecACLAuthorizationSign', :pointer
attach_variable 'kSecACLAuthorizationEncrypt', :pointer
attach_variable 'kSecACLAuthorizationDecrypt', :pointer
attach_variable 'kSecACLAuthorizationMAC', :pointer
attach_variable 'kSecACLAuthorizationDerive', :pointer
end

module Keychain
class Acl < Sec::Base
register_type 'SecACL'

attr_reader :applications, :description, :prompt

def initialize(ptr)
super(ptr)

applications_ref = FFI::MemoryPointer.new(:pointer)
description_ref = FFI::MemoryPointer.new(:pointer)
prompt_ref = FFI::MemoryPointer.new(:pointer)
status = Sec.SecACLCopyContents(self, applications_ref, description_ref, prompt_ref)
Sec.check_osstatus(status)

unless applications_ref.read_pointer.null?
applications_cf = CF::Base.typecast(applications_ref.read_pointer).release_on_gc
@applications = applications_cf.to_ruby
applications_cf.release
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is releaseing applications_ref a second time

end

unless description_ref.read_pointer.null?
description_cf = CF::Base.typecast(description_ref.read_pointer).release_on_gc
@description = description_cf.to_ruby
end

unless prompt_ref.read_pointer.null?
prompt_cf = CF::Base.typecast(prompt_ref.read_pointer).release_on_gc
@prompt = prompt_cf.to_ruby
end
end

def authorizations
authorizations_ref = Sec.SecACLCopyAuthorizations(self)
authorizations_cf = CF::Base.typecast(authorizations_ref)
result = authorizations_cf.to_ruby
authorizations_cf.release
result
end

def delete
status = Sec.SecACLRemove(self)
Sec.check_osstatus(status)
end

def applications=(apps)
apps_cf = apps ? apps.to_cf : nil
description_cf = apps ? self.description.to_cf : nil
prompt_cf = apps ? self.prompt.to_cf : nil
status = Sec.SecACLSetContents(self, apps_cf, description_cf, prompt_cf)
Sec.check_osstatus(status)
end
end
end
Loading