SecKeyGeneratePair Always Require Password?

I'm trying to generate an asymmetric key pair on a Mac without the default ACLs, but it doesn't look like there are recognized dictionary keys that can be passed in to SecKeyGeneratePair() to do this automatiically. When removing the ACLs from the private key immediately afterwards, the user is prompted, which is not at all the experience I want, especially since I'm just trying to modify the key I just generated and ostensibly belongs to me. Below I have my current implementation.

var public:SecKey?, private:SecKey?
let options:CFDictionary = [kSecAttrKeyType as String:kSecAttrKeyTypeEC as String, kSecAttrKeySizeInBits as String: SecKeySizes.secp521r1.rawValue] as CFDictionary
guard SecKeyGeneratePair(options, &public, &private) == errSecSuccess,
  let publicKey = public else {
  return nil
}
var acc:SecAccess?
if let privateKey = private, let item = privateKey.keychainItem, SecKeychainItemCopyAccess(item, &acc) == errSecSuccess, let access = acc {
  (SecAccessCopyMatchingACLList(access, kSecACLAuthorizationSign) as? [SecACL])?.forEach {
  var apps:CFArray?, desc:CFString?, selec = SecKeychainPromptSelector()
  if SecACLCopyContents($0, &apps, &desc, &selec) == errSecSuccess, let description = desc {
  SecACLSetContents($0, [] as CFArray, description, .requirePassphase)
  }
  }
  SecKeychainItemSetAccess(item, access)
}

Replies

I'm trying to generate an asymmetric key pair on a Mac without the default ACLs …

OK, this is definitely a “What are you really trying to do?” moment. Why are you trying to create keys without ACLs? And what context is this code running in (unsigned, Developer ID signed, Mac App Store signed)?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I should explain. First, this is a Swift (shell) script, so the ACL will say ”swift” no matter what (as far as I can tell). The script may change from time-to-time in the repository, so there’s that as well (detached signatures wouldn’t help). Overall I’m trying to provide some convenience in a safe way (always prompt, at least until the user specifies otherwise) which is also plain text and can be checked by more paranoid users.


I was originally interested because it looks like SecItemImport() will offer to do the same thing with kSecKeyNoAccessControl, so I assumed a similar invocation would be possible for key generation.