Add Certificate to IOS Keychain in Swift

im trying to write the root cert to the app keychain so I can talk to the server serving the signed cert itself.

class func setCertificate(certData: NSData, forKey keyName: String) -> Bool
    {
        var secCert = SecCertificateCreateWithData(kCFAllocatorDefault, certData)

        var keychainQueryDictionary: NSMutableDictionary = self.setupKeychainQueryDictionaryForKey(keyName)

        keychainQueryDictionary[kSecClassCertificate as NSString] = secCert.takeRetainedValue()

        // Protect the keychain entry so it only valid when the device is unlocked
        keychainQueryDictionary[SecAttrAccessible] = kSecAttrAccessibleWhenUnlocked

        // Disable icloud sync of keychain data
        keychainQueryDictionary[kSecAttrSynchronizable as NSString] = kCFBooleanFalse

        let status: OSStatus = SecItemAdd(keychainQueryDictionary, nil)

        println(status)

        if status == errSecSuccess
        {
            return true
        }

        return false
    }

      

But the returned OSStatus is -50 (one or more parameters passed to the function where they are not valid.), I've tried many casts, etc., but didn't get it anywhere. The certificate is definitely valid as SecCertificateCreateWithData will return null if there is a problem with its format.

This is my function for setting up a keychain request

private class func setupKeychainQueryDictionaryForKey(keyName: String) -> NSMutableDictionary
    {
        // Setup dictionary to access keychain and specify we are using a generic password (rather than a certificate, internet password, etc)
        var keychainQueryDictionary: NSMutableDictionary = [SecClass:kSecClassGenericPassword]

        // Uniquely identify this keychain accessor
        keychainQueryDictionary[SecAttrService] = KeychainManager.serviceName

        // Uniquely identify the account who will be accessing the keychain
        var encodedIdentifier: NSData? = keyName.dataUsingEncoding(NSUTF8StringEncoding)

        keychainQueryDictionary[SecAttrGeneric] = encodedIdentifier

        keychainQueryDictionary[SecAttrAccount] = encodedIdentifier

        return keychainQueryDictionary
    }

      

Has anyone done this quick or any advice from anyone?

Greetings

+3


source to share


1 answer


In fact, I found what was wrong with Adrian's code. I found a link which is from Apple and is very helpful.

To add a certificate to the keychain, we have to write the following lines:



let secCert = SecCertificateCreateWithData(nil, certInDer as CFData) // certInDer is Certificate(.der) data
        var keychainQueryDictionary = [String : Any]()

        if let tempSecCert = secCert {
            keychainQueryDictionary = [kSecClass as String : kSecClassCertificate, kSecValueRef as String : tempSecCert, kSecAttrLabel as String: "My Certificate"]
        }

        let summary = SecCertificateCopySubjectSummary(secCert!)! as String
        print("Cert summary: \(summary)")

        let status = SecItemAdd(keychainQueryDictionary as CFDictionary, nil)

        guard status == errSecSuccess else {
            print("Error")
            return
        }

        print("success")

      

Hope this helps everyone ...

0


source







All Articles