Keychain Services API

Hi folks,

I’m looking to move some of the keychain interaction of a project I maintain (https://github.com/macmule/ADPassMon) from using the security binary to the Keychain Services API (https://developer.apple.com/library/prerelease/mac/documentation/Security/Reference/keychainservices/#//apple_ref/doc/uid/TP30000898-CH1g-286517).

But I’m struggling to figure out how best to add/call the API from my ADPassMon.

I’ve added the framework the to app in Xcode in a test project, which main.m looks like:

#import <Cocoa/Cocoa.h>
#import <AppleScriptObjC/AppleScriptObjC.h>
#import <Security/SecKeychain.h>

int main(int argc, const char * argv[]) {
    [[NSBundle mainBundle] loadAppleScriptObjectiveCScripts];
    return NSApplicationMain(argc, argv);
}

I’ve then tried to declare a property as per, the below in the AppDelegate:

script AppDelegate
	property parent : class "NSObject"
    property SecKeychain : class "SecKeychain"
    property defaultKeychain : ""
	
	-- IBOutlets
	property theWindow : missing value
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened
        set keychain_status to SecKeychain's SecKeychainGetVersion
        log keychain_status

	end applicationWillFinishLaunching_
	
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script

But, I’m getting the below with the above:

*** -[AppDelegate applicationWillFinishLaunching:]: Can't get SecKeychainGetVersion of class "SecKeychain". (error -1728)

Help appreciated!

I don’t think you’ll be able to do that from ASObjC. You call functions such as SecKeychainGetVersion() like this:

 current application's SecKeychainGetVersion(var)

The problem is not so much the function as the fact that the argument is of a type (pointer to an integer) that ASObjC doesn’t support.

Thanks, Shane.

That was an example, one of the keys I was after is SecKeychainGetStatus https://developer.apple.com/library/mac/documentation/Security/Reference/keychainservices/#//apple_ref/c/func/SecKeychainGetStatus.

Presumably that’s the same?

Yes, same sort of problem. With a few exceptions, the only functions you can call from ASObjC are those that take no arguments.

Yea, that’s a shame.

I’ve done some NS stuff (NSTask, NSTimer, NSArray etc).

The other shame is that the security binary does not function as per the underlying API, which might have helped smooth out some code as well as allowed me to amend ADPassMon to not only update & manage the login.keychain but also local items (as per: https://github.com/google/macops-keychainminder).

Hmm… is there not a way to address ObjC as ObjC? then I could pass a value to a variable then back to AppleScript?

I’m not sure what you mean. You can add an Objective-C class and wrap the code in an ASObjC method that you can call from ASObjC.

That’s kind of what I thought I was doing.

Or rather, an avenue of approach I was hoping to go down. But am missing some level of understanding, & if that even something that would work for this?

Just add your own Objective-C class to your project, and wrap the security code in an Objective-C method. Then call it from your ASObjC code.

Is this a valid example? http://macscripter.net/viewtopic.php?id=43556

Sorry, but I’m not following.

Yes, that’s the sort of thing.