How do I programmatically import a certificate into my iOS app's keychain and pass the identity to a server when needed?

夙愿已清 提交于 2019-12-02 23:00:22

The following code should do the trick :

NSMutableDictionary *secIdentityParams = [[NSMutableDictionary alloc] init];
[secIdentityParams setObject:(id)myIdentity forKey:(id)kSecValueRef];
OSStatus status = SecItemAdd((CFDictionaryRef) secIdentityParams, NULL);

You interact with the Keychain by passing in a dictionary of key-value pairs that you want to find or create. Each key represents a search option or an attribute of the item in the keychain. Keys are pre-defined constants that you must use depending on the type of data to be stored. Those keys can be found in Apple's developer doc.

I think Apple's source code is indeed missing the allocation of persistentRef. They should have added such declaration at the beginning of the method :

NSData *persistentRef = nil; 

Note that use of persistent reference is not mandatory. The above code should work just fine. As Apple explains it well :

Because a persistent reference remains valid between invocations of your program and can be stored on disk, you can use one to make it easier to find a keychain item that you will need repeatedly

source : https://developer.apple.com/library/ios/#documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-DontLinkElementID_10

Swift 4.0

 if let url = Bundle.main.url(forResource: "XXX", withExtension: "pem") {

            let PKCS12Data = NSData(contentsOf: url)
            let inPKCS12Data = CFDataCreate(kCFAllocatorDefault, PKCS12Data!.bytes.assumingMemoryBound(to: UInt8.self), (PKCS12Data?.length)!)

            let keys: [CFString] = [kSecImportExportPassphrase]
            let values: [CFTypeRef] = []

            let keysPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: keys.count)
            keysPointer.initialize(to: keys)

            let valuesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: values.count)
            valuesPointer.initialize(to: values)

            let optionsDictionary = CFDictionaryCreate(kCFAllocatorDefault, keysPointer, valuesPointer, 1, nil, nil)

            var items = CFArrayCreate(kCFAllocatorDefault, UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 0), 0, nil)
            let securityError = SecPKCS12Import(inPKCS12Data!, optionsDictionary!, &items)
            if (securityError == 0) {
                print("Certificate installed Successfully")
            } else {
                print("Certificate installation failed")
            }

    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!