Yubico / yubikit-ios

Yubico Mobile iOS SDK - YubiKit
Apache License 2.0
195 stars 43 forks source link

Specify optional frameworks as weak for all installation methods #86

Closed bmwalters closed 2 years ago

bmwalters commented 2 years ago

Problem

Attempting to run an app that links to YubiKit on an iOS 12 device fails with

dyld: Library not loaded: /System/Library/Frameworks/CryptoTokenKit.framework/CryptoTokenKit
  Referenced from: /private/var/containers/Bundle/Application/17E1DCD2-882E-438C-9138-2F8BA45A786D/Pass.app/Frameworks/YubiKit_3C81011B9560B8C8_PackageProduct.framework/YubiKit_3C81011B9560B8C8_PackageProduct
  Reason: image not found

Fixing this issue results in the same error but caused by CoreNFC assuming the device does not suppot NFC (e.g. iPhone 6).

Solution

Apple's solution to this problem is to "weakly link" to frameworks that may not be present. At dynamic load time symbols from missing frameworks will be bound to NULL. The app must then simply avoid using these symbols (could be enforced by app-level @available checks).

This has to be configured separately for each of the three supported installation methods.


jensutbult commented 2 years ago

Great thanks for the efforts you put into investigating and fixing this issue! We will use the weak linking fix for NFC in #80 and resolve the problems we got with CryptoTokenKit in #89. However, I really would like to merge the documentation changes you made into the next release. Could you modify your PR so it only contains that?

bmwalters commented 2 years ago

Thanks @jensutbult! I think with the recent developments the README change is actually no longer necessary.

The main reason I added it was due to the CryptoTokenKit change which will no longer be an issue. Furthermore the main NFC entrypoints in YubiKit all have API_AVAILABLE(ios(13.0)) annotations which would prevent the crash entirely: see YKFNFCConnection.h and YubiKitManager.h. The only crash I could find on iOS 12 was with

YubiKitManager.shared.otpSession.requestOTPToken { result, error in
    print(result, error)
}

since YKFNFCOTPSession correctly has an API_AVAILABLE(ios(11.0)) and my iPhone 6 lacks CoreNFC.framework.

requestOTPToken uses an assertion in dev builds and documents the behavior in otp.md, so in theory nothing needs to be updated. Though the method could be changed to return a handle-able error which would eliminate all crashes I could see.