I am reading a p12 file and obtaining a SecIdentityRef and then add this Identity to keychain as follows
let certData:NSData = NSFileManager.defaultManager().contentsAtPath(filePath)!
let passDictionary:NSMutableDictionary = NSMutableDictionary()
passDictionary.setValue("pass",
forKey: kSecImportExportPassphrase as String)
print(kSecImportExportPassphrase as String)
var items: CFArray?
let error = SecPKCS12Import(certData, passDictionary, &items)
let unwrappedItems:CFArray = items!
if error == noErr && CFArrayGetCount(items) > 0{
let certChain = unwrappedItems as [AnyObject] as NSArray
let certificateDict = certChain.objectAtIndex(0)
var privateKeyRef : SecKeyRef? = nil
var certificateRef: SecCertificate? = nil
let secIdentity:SecIdentityRef = certificateDict.valueForKey(kSecImportItemIdentity as String) as! SecIdentityRef
let subject:NSString=SecCertificateCopySubjectSummary(certificateRef!)
let keyChainQuery:NSMutableDictionary = NSMutableDictionary(
objects: [String(kSecClassIdentity),subject,kCFBooleanTrue,String(kSecAttrAccessibleAlwaysThisDeviceOnly),secIdentity],
forKeys: [String(kSecClass),String(kSecAttrLabel), String(kSecAttrCanSign),String(kSecAttrAccessible),String(kSecValueRef)])
let status:OSStatus = SecItemAdd(keyChainQuery as CFDictionaryRef, nil)
This seems to work fine and returns 0 as status code, but when I try to read this item from the keychain:
var identity: AnyObject?
let searchQuery: NSMutableDictionary = NSMutableDictionary(objects: [String(kSecClassIdentity), kCFBooleanTrue], forKeys: [String(kSecClass),String(kSecReturnRef)])
let status:OSStatus = SecItemCopyMatching(searchQuery as CFDictionaryRef, &identity)
I receive a -25300 error code (not found item) and nil in identity, I am using iOS 9.1 as base SDK, what am I doing wrong?
I’m not sure what’s going on with your code—I found it quite hard to understand given the lack of formatting and your use of
+dictionaryWithObjects:keys:
—but here’s how I’d do this (built with Xcode 7.1, tested on iOS 9.1).
func identityForImportedPKCS12Data(pkcs12Data: NSData, password: String) throws -> SecIdentity {
func securityThrower(err: OSStatus) throws {
if err != errSecSuccess {
throw NSError(domain: NSOSStatusErrorDomain, code: Int(err), userInfo: nil)
}
}
var importResult: CFArray? = nil
try securityThrower( SecPKCS12Import(pkcs12Data, [
kSecImportExportPassphrase as String: password
] as CFDictionary, &importResult) )
let dictionaries = importResult! as NSArray as! [[String:AnyObject]]
let identity = dictionaries.first![kSecImportItemIdentity as String] as! SecIdentity
let label = NSUUID().UUIDString
try securityThrower( SecItemAdd([
kSecAttrLabel as String: label,
kSecValueRef as String: identity
] as CFDictionary, nil) )
var copyResult: AnyObject? = nil
try securityThrower( SecItemCopyMatching([
kSecClass as String: kSecClassIdentity,
kSecAttrLabel as String: label,
kSecReturnRef as String: true
], ©Result) )
let copiedIdentity = copyResult as! SecIdentity
return copiedIdentity
}
Note that I’ve labelled the identity with a UUID rather than the subject summary because there’s no guarantee that the subject summary will be unique.
Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"