Posts

Post not yet marked as solved
0 Replies
644 Views
I want to open photos within the photo app with my app. My app already supports opening the file types public.png, public.jpeg, public.image <key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeName</key> <string>My Files</string> <key>LSHandlerRank</key> <string>Alternate</string> <key>LSItemContentTypes</key> <array> <string>com.adobe.pdf</string> <string>public.png</string> <string>public.jpeg</string> </array> </dict> </array> It works fine when a file of the given filetypes is opened in the Files App or as Attachment from Mail. If I click the share icon, my app appears in the Share Sheet. When selected, my app opens in full screen mode and is able to access the file. But when I select a Photo in the Photo app, my app does not appear as option in the share sheet. Does anybody know why? I am not interested in opening a Share Extension Sheet of my app. What I want is opening my app in full screen mode with the ability to access the shared file. I can see apps which are able to do exactly what I want. But I do not find any hints in the official docs. Has anybody hints on how I can achieve this?
Posted
by reto.
Last updated
.
Post marked as solved
6 Replies
1.7k Views
In my app i use the iOS keychain to store a private key (ec-256) for message signature.The code is working since iOS 11, but I can experience with iOS 13, that the TouchID popup when accessing the private key in the keychain is missing the custom text. It only shows one line: TouchID for "&amp;lt;APP NAME&amp;gt;", the custom text is not displayed. Using iOS 11 and iOS 12, there is a second line in the TouchID popup below that line.Code to generate/store the key in the keychain:let access: SecAccessControl if #available(iOS 11.3, *) { access = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, [.privateKeyUsage, .biometryCurrentSet], nil)! } else { access = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, [.privateKeyUsage, .touchIDCurrentSet], nil)! } let attributes = [ kSecAttrKeyClass: kSecAttrKeyClassPrivate, kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits: 256, kSecAttrTokenID: kSecAttrTokenIDSecureEnclave, kSecPrivateKeyAttrs: [ kSecAttrIsPermanent: true, kSecAttrApplicationTag: keyTag, kSecAttrAccessControl: access ] as [String: Any] ] as [String: Any] var error: Unmanaged&amp;lt;CFError&amp;gt;? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &amp;amp;error) else { throw error!.takeRetainedValue() as Error }Code to retrieve the private key to sign a message:let authenticationText = NSLocalizedString("BIOMETRICS_LOGIN__FINGERPRINT_REQUEST_MESSAGE", comment: "") let query = [ kSecClass: kSecClassKey, kSecAttrKeyClass: kSecAttrKeyClassPrivate, kSecUseOperationPrompt: "\(authenticationText) \(accountId)", kSecAttrApplicationTag: keyTag, kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, kSecReturnRef: true ] as [String: Any] var item: CFTypeRef? let status = SecItemCopyMatching(query as CFDictionary, &amp;amp;item) guard status == errSecSuccess else { throw AccountStorageError.privateKeyNotFound } let privateKey = item as! SecKeyThe above code works in all supported iOS versions (11, 12, 13 up to 13.2.3), private keys can be stored and retrieved, but only on iOS 13 devices, the text specified in kSecUseOperationPrompt is not displayed in the TouchID popup.Is there something wrong or is this a known issue in iOS 13?
Posted
by reto.
Last updated
.
Post marked as solved
2 Replies
1.8k Views
I'am trying to implement a Secure Enclave based authentication with a server. During the registration flow the server expects a JWK (RFC7517) containing the public key in the following format:{ "kty":"EC", "crv":"P-256", "x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU", "y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0", }During the login process the server sends a challenge string to the client. This challenge needs to be signed using the private key in the Secure Enclave and sent back so the server. The server verifies the signature with the previousely sent public Key.I generate the Key Pair using the following code:let attributes: [String: Any] = [ kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits as String: 256, kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave, kSecPrivateKeyAttrs as String: [ kSecAttrIsPermanent as String: true, kSecAttrApplicationTag as String: keyTag, kSecAttrAccessControl as String: access ] ] var error: Unmanaged?? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &amp;error) else { throw error!.takeRetainedValue() as Error } guard let pubKey = SecKeyCopyPublicKey(privateKey) else { throw AccountStorageError.publicKeyCreationFailed } guard let externalRep = SecKeyCopyExternalRepresentation(publicKey, &amp;error) else { throw error!.takeRetainedValue() as Error }If I debug print the public key I get the following information:&lt;SecKeyRef curve type: kSecECCurveSecp256r1, algorithm id: 3, key type: ECPublicKey, version: 4, block size: 256 bits, y: FBCA97607E4F5B2A97B404F5E14B4650ABC5261F4CB811C36F96BFC7A70829BF, x: 7790A8263CCF5DD26BDB06B6D697AE8C31D747A89241099363FE666831D2856F, addr: 0x108001d30&gt;The variable externalRep has the following format (looks to me like Octet representation):&lt;047790a8 263ccf5d d26bdb06 b6d697ae 8c31d747 a8924109 9363fe66 6831d285 6ffbca97 607e4f5b 2a97b404 f5e14b46 50abc526 1f4cb811 c36f96bf c7a70829 bf&gt;So my question is the following: How do I transform this externalRepresentation into the format expected by JWK (EC Point representation)?. Of course I can find all the math behind that conversion in the Internet (e.g. here: https://web.archive.org/web/20140701131201/http://www.secg.org/collateral/sec1_final.pdf,Chapter 2.3.4) but I am wondering if iOS APIs can help me with this task. Under the hood this seems to be implemented (to me the debug printout of the SecKey is exactly in the representation I am targeting). How can I do this the easiest way?
Posted
by reto.
Last updated
.