I'm trying to automate the process of building iphone apps with a particular certificate. So imagine if different users uploaded their cert into the system and it was immediately available to code sign against. I want to do this without any interaction. I also don't want to clutter up the system or logon keychain with different user certificates. To this end I have:
- turned off the requirement in XCODE to require code signing for a a build.
- developed a ruby script to build an application via the xcodebuild command line tool
- created a script to automatically create a new keychain for a user of my system
- written a script to code sign a built iphone app.
Everything works, but I need to manually hit enter when the codesign program tries to exercise the sign permission. My keychains are all unlocked. Oddly enough it works if I make the keychain the default keychain, but that isn't scalable ie I could only have one build process going at any given time.
When I manually click always allow for that process, I get an entry in my keychain dump that looks like this:
entry 1:
authorizations (6): decrypt derive export_clear export_wrapped mac sign
don't-require-password
description: privateKey
applications (2):
0: /usr/bin/codesign (OK)
So I'm thinking that I need to use the authorize command in security to pre-autorize codesign for those permissions. The security man page is pretty poor. I can't seem to get it to work using commands like this:
security -v authorize -uew sign | /usr/bin/codesign [code sign vars pointing to app and a specific keychain]
Does anyone have any ideas?
If you import your certificate into your keychain with a -A it will allow access to all programs trying to request that cert. This isn't very secure but works. You can also use -T to limit it to a particular app. Look up the import param found in man security.
On my system, once the keychain is unlocked with
security unlock-keychain
I just let xcodebuild to do both the build and the code signing.
If your keychanins are unlocked, it shouldn't be necessary
to use the above call.
You might also want to check the command execute-with-privileges
of security.
I'd like to add to the answer pool here, but also reopen part of the question that I don't think was answered.
The following command imports an identity (cert + private key) and specifies that it should "always allow" code sign access to it (preventing Keychain Access alert from promoting user for a button click):
`security import Targets/CurrentTarget/Certificate.p12 -k #{KEYCHAIN} -P "#{cert_pwd}" -T /usr/bin/codesign`
This command allows all applications access, rather than just code sign:
security import Targets/CurrentTarget/Certificate.p12 -k #{KEYCHAIN} -P "#{cert_pwd}" -A
Either of these commands will take care of the dialogs that pop up each time you use a private key in your Keychain. HOWEVER, they will NOT take care of the similar alert that pops up the very first time you request permission to use a private key. This alert will appear on first use and ask you to choose always allow, deny or allow. Every time after that (if you use the -T
or -A
options above, assuming the key remains in your keychain) you won't see a dialog.
My question is: how can you eliminate the alert that appears on first use?
I've considered using Apple Script to automate tapping the always allow button but because the alert is triggered in the middle of the xcodebuild
command I'm not sure this would work. Any help would be much appreciated!
Just to add to all the answers above: even even your key/certificate is not password-protected, you need to pass -P ""
(empty password) to security import
.
Copying the certificates from the Login keychain to the System keychain works nicely in my case, and as a result you don't need to do any command-line unlocking.
Regarding dialogs that pop up each time you use a private key in your Keychain, this apple script will take care of the similar alert that pops up the very first time you request permission to use a private key.
#!/usr/bin/osascript
tell application "System Events"
tell window 1 of process "SecurityAgent"
click button "Always Allow" of group 1
end tell
end tell