0

I have a KeyChain class where I sign a string. I got Thread 8: EXC_BAD_ACCESS (code=257, address=0x3fd574bc6a7ef9db) error at SecKeyIsAlgorithmSupported function. I could not figure out why this error pops up. When I use the getquery variable which is commented it all works fine except on iPhone 13 pro max devices. So I wanted to try different queries hoping that can work on all devices. But in that case SecKeyIsAlgorithmSupported function crashes giving this error EXC_BAD_ACCESS. Here is the function I use.

func signString(clearString:String) -> Bool {
        /*let getquery: [String: Any] = [kSecClass as String: kSecClassKey,
                                       kSecAttrApplicationTag as String: serviceName,
                                       kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
                                       kSecReturnRef as String: true]*/
        
        let getquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
                                       kSecAttrService as String: serviceName,
                                       kSecReturnAttributes as String: kCFBooleanTrue!,
                                       kSecMatchLimit as String: kSecMatchLimitAll]
        
        var item: CFTypeRef?
        let status = SecItemCopyMatching(getquery as CFDictionary, &item)
        print("status = ",status)

        if (status != errSecSuccess) {
            print("No key found")
            return false
        }
        else {
            let key = item as! SecKey
            self.privateKey = key
            
            let data = clearString.data(using: .utf8)! as CFData
            let algorithm: SecKeyAlgorithm = .ecdsaSignatureMessageX962SHA256
            
            if (self.privateKey != nil) {
                guard SecKeyIsAlgorithmSupported(self.privateKey!, .sign, algorithm) else {
                    print("Algorithm Not Supported")
                    return false
                }
                
                var error: Unmanaged<CFError>?
                guard let signature = SecKeyCreateSignature(self.privateKey!,algorithm, data, &error) as Data? else {
                    print("signature error")
                    return false
                }
                
                self.signedString = signature.base64EncodedString()
                return true
            }
            else {
                print("Private Key is null")
                return false
            }
        }
    }

I wish there would be a way to avoid this crash. I searched about it but I could not find a way to fix that. Any help will be appreciated. Thanks in advance.

Hilal
  • 902
  • 2
  • 22
  • 47

1 Answers1

1

Your get query states kSecMatchLimitAll, which will result in a CFArray object as a result. You can easily fix that by changing it to kSecMatchLimitOne, or you can loop the list, by casting it to an array.

let keys = item as! [SecKey]
for key in keys {
    SecKeyIsAlgorithmSupported(key, .sign, . ecdsaSignatureMessageX962SHA256)
}

Do note that not all generic items, or likely none, are valid SecKey objects. It appears you're using ECC keys, which can be stored using the kSecClass: kSecClassKey attribute. I would highly recommend storing it as what it is, instead of storing it as a generic password (kSecClassGenericPassword) as you're doing right now

Bram
  • 2,718
  • 1
  • 22
  • 43
  • Thank you so much for your answer it helped a lot. Actually it was `kSecClassKey` but that was not work on iPhone 13 pro max devices, to fix that I wanted to try with `kSecClassGenericPassword`. You may see [in here](https://stackoverflow.com/questions/73663960/secitemcopymatching-returns-errsecitemnotfound-25300-only-on-iphone-13-pro-ma) if you have any chance to take a look at it, I would really appreciate it =) – Hilal Sep 14 '22 at 14:50