Posts

Post not yet marked as solved
7 Replies
914 Views
Hi,I'm working on a SSL client authentication scheme, schematically:- generate a RSA (for now) keypair on the phone (tagging it with a applcation data)- generating PKCS#10 data (public key and meta data), send it to a server to be signed- getting a signed certificate back and importing into the keychainWhen receiving client authentication chanlenge, I search for the identity, using the tag as the query, then create a URL credential.It works on iOS 12However, if I try on a iOS 13 device, I get -34018 (Missing entitlements) systematically when I use SecCopyItemMatching.In development, the certificate is signed by a self-signed CA.I have no need for keychain group, but tried to add the app-identifier as a keychain group in the entitlements, but the result is the same.Could it be a iOS 13 bug or some change in Security?On iOS13, I can get the private key and the cert separately (lookup using the public key hash) so I don't understand why I couldn't get the identity.If anyone have some insight on this, I'll take it.Thanks!Jean-AlexisHere are some excerpt from the code: func generateCSR() -> Data? { let keyParameters : [CFString: Any] = [ kSecAttrKeyType: kSecAttrKeyTypeRSA, kSecAttrKeySizeInBits: 2048, kSecPublicKeyAttrs: [ kSecAttrLabel: "My Public Key" as NSString, kSecAttrIsPermanent: true, ], kSecPrivateKeyAttrs: [ kSecAttrLabel: "My Private Key" as NSString, kSecAttrApplicationTag: Self.keyTag, kSecAttrIsPermanent: true, // kSecAttrAccessControl: controlAccess!, ] ] var privateKey: SecKey! // on success, privateKey will not be nil guard withCFErrorCheck(context: "Generate key pair", { privateKey = SecKeyCreateRandomKey(keyParameters as CFDictionary, $0) }) else { return nil } return pkcs10(privateKey) } func handleCertResponse(data: Data?, response: URLResponse?, error: Error?) { // pkcs1DER was generated by openssl, received and decoded from Data, certificate import seems to work guard let signedKey = SecCertificateCreateWithData(nil, pkcs1DER as CFData) else { print ("Invalid DER X.509 certificate") return } let keyAttributes : [CFString: Any] = [kSecClass: kSecClassCertificate, kSecValueRef: signedKey, kSecAttrLabel: Self.certificateLabel, kSecReturnRef: true, kSecReturnAttributes: true, ] var returned: CFTypeRef? let status = SecItemAdd(keyAttributes as CFDictionary, &returned) guard isStatusOK(status, context: "Add certificate in keychain") else { return } let certAttributes = returned as! CFDictionary as Dictionary print ("Certificate values: \(certAttributes)") } // func getIdentity() -> SecIdentity? { let getquery: [CFString: Any] = [kSecClass: kSecClassIdentity, kSecAttrApplicationTag: Self.keyTag, kSecReturnRef: true, ] var item: CFTypeRef? let statusSearch = SecItemCopyMatching(getquery as CFDictionary, &item) guard isStatusOK(statusSearch, context: "Searching identity") else { return nil } let identity = item as! SecIdentity print ("Identity is:\(identity)") return identity }
Posted Last updated
.