@vppos/react-native-nfc 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/NFCSDK.podspec +40 -0
- package/android/build.gradle +85 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +31 -0
- package/android/src/main/AndroidManifestNew.xml +30 -0
- package/android/src/main/java/com/nfcsdk/ChipReader.kt +237 -0
- package/android/src/main/java/com/nfcsdk/NFCSDKModule.kt +78 -0
- package/android/src/main/java/com/nfcsdk/NFCSDKPackage.kt +17 -0
- package/android/src/main/java/com/nfcsdk/NFCScanActivity.kt +299 -0
- package/android/src/main/java/com/nfcsdk/utils/Dg13Parser.kt +278 -0
- package/android/src/main/java/com/nfcsdk/utils/FaceExtractor.kt +40 -0
- package/android/src/main/java/com/nfcsdk/utils/MrzUtils.kt +75 -0
- package/android/src/main/res/drawable/bg_nfc_bottom_sheet.xml +13 -0
- package/android/src/main/res/drawable/bg_nfc_sheet_handle.xml +9 -0
- package/android/src/main/res/layout/activity_nfc.xml +110 -0
- package/android/src/main/res/values/styles.xml +10 -0
- package/android/src/main/res/xml/nfc_tech_filter.xml +8 -0
- package/ios/ChipReader.swift +258 -0
- package/ios/NFCSDK-Bridging-Header.h +2 -0
- package/ios/NFCSDK.mm +9 -0
- package/ios/NFCSDK.swift +112 -0
- package/ios/NFCSDKSession.swift +5 -0
- package/ios/utils/DG13Parser.swift +302 -0
- package/ios/utils/MrzUtils.swift +49 -0
- package/lib/module/errors.js +9 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/index.js +118 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/errors.d.ts +4 -0
- package/lib/typescript/src/errors.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +80 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +45 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +155 -0
- package/src/errors.ts +6 -0
- package/src/index.tsx +141 -0
- package/src/types.ts +45 -0
- package/vendor/ios-passport-reader/CHANGELOG +362 -0
- package/vendor/ios-passport-reader/CODE_OF_CONDUCT.md +77 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/AppDelegate.swift +39 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/Contents.json +158 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-72.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-76.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small-50.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small-50@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/ios-marketing.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon~ipad.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon~ipad@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/Contents.json +6 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/background.imageset/Contents.json +21 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/background.imageset/background.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/head.imageset/Contents.json +21 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/head.imageset/head.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Base.lproj/LaunchScreen.storyboard +25 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Extensions/FileManagerExt.swift +16 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Extensions/StringExt.swift +40 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Extensions/UIApplicationExt.swift +21 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Info.plist +77 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Model/PassportUtils.swift +76 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Model/SettingsStore.swift +107 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/NFCPassportReader.entitlements +10 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/SceneDelegate.swift +57 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/DetailsView.swift +197 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/ExportPassportView.swift +164 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/HelperViews/CheckBoxView.swift +48 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/HelperViews/ViewExt.swift +20 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/HelperViews/ViewModifiers.swift +41 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/MRZEntryView.swift +125 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/MRZScannerViewController.swift +90 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/MainView.swift +214 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/PassportSummaryView.swift +111 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/PassportView.swift +73 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/SettingsView.swift +63 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/StoredPassportView.swift +152 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/masterList.pem +32 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/readme.md +10 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcodeproj/project.pbxproj +695 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcodeproj/xcshareddata/xcschemes/NFCPassportReader.xcscheme +106 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcworkspace/contents.xcworkspacedata +10 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderAppTests/DataGroupParsingTests.swift +189 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderAppTests/Info.plist +22 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderAppTests/NFCPassportReaderTests.swift +260 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderAppTests/PACETests.swift +112 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/Podfile +22 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/Podfile.lock +35 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/README.md +2 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/AppDelegate.swift +39 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/Contents.json +158 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-72.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-76.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small-50.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small-50@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/ios-marketing.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon~ipad.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon~ipad@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/Contents.json +6 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/background.imageset/Contents.json +21 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/background.imageset/background.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/head.imageset/Contents.json +21 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/head.imageset/head.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Base.lproj/LaunchScreen.storyboard +25 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Extensions/FileManagerExt.swift +16 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Extensions/StringExt.swift +40 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Extensions/UIApplicationExt.swift +21 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Info.plist +79 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Model/PassportUtils.swift +99 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Model/SettingsStore.swift +98 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Model/SettingsStoreCAN.swift +75 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/LICENSE +21 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/PreviewView.swift +34 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/StringUtils.swift +160 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/ViewController.swift +320 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/VisionViewController.swift +163 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/NFCPassportReader.entitlements +10 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/SceneDelegate.swift +58 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/CANViews/CanKeyView.swift +251 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/CANViews/MRZEntryViewCanKey.swift +65 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/CANViews/PassportViewCAN.swift +73 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/DetailsView.swift +193 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/ExportPassportView.swift +164 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/HelperViews/CheckBoxView.swift +48 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/HelperViews/ViewExt.swift +20 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/HelperViews/ViewModifiers.swift +41 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/MRZEntryView.swift +125 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/MRZScannerViewController.swift +90 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/MainView.swift +264 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/PassportSummaryView.swift +111 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/PassportView.swift +73 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/SettingsView.swift +47 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/StoredPassportView.swift +149 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/masterList.pem +32 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/readme.md +10 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp.xcodeproj/project.pbxproj +683 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +25 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp.xcodeproj/xcshareddata/xcschemes/NFCPassportReader.xcscheme +106 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderAppTests/DataGroupParsingTests.swift +190 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderAppTests/Info.plist +22 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderAppTests/NFCPassportReaderTests.swift +260 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderAppTests/PACETests.swift +112 -0
- package/vendor/ios-passport-reader/LICENSE +21 -0
- package/vendor/ios-passport-reader/NFCPassportReader.podspec +27 -0
- package/vendor/ios-passport-reader/Package.swift +29 -0
- package/vendor/ios-passport-reader/README.md +141 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/AES_3DES_DESEncryption.swift +377 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/BACHandler.swift +194 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/ChipAuthenticationHandler.swift +224 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroupHash.swift +16 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroupParser.swift +36 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/ActiveAuthenticationInfo.swift +69 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/COM.swift +61 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/CardAccess.swift +38 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/ChipAuthenticationInfo.swift +135 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/ChipAuthenticationPublicKeyInfo.swift +53 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup.swift +103 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup1.swift +111 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup11.swift +66 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup12.swift +75 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup14.swift +37 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup15.swift +46 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup2.swift +163 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup7.swift +46 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroupId.swift +105 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/NotImplementedDG.swift +16 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/PACEInfo.swift +415 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/SOD.swift +240 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/SecurityInfo.swift +136 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Errors.swift +148 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Logging.swift +32 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Models/FaceImageInfo.swift +161 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/NFCPassportModel.swift +540 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/NFCViewDisplayMessage.swift +60 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/OpenSSLUtils.swift +705 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/PACEHandler.swift +627 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/PassportReader.swift +387 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Resources/PrivacyInfo.xcprivacy +14 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/ResponseAPDU.swift +25 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/SecureMessaging.swift +301 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/SecureMessagingSessionKeyGenerator.swift +156 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/SimpleASN1DumpParser.swift +173 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/TagReader.swift +374 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Utils.swift +430 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/X509Wrapper.swift +168 -0
- package/vendor/ios-passport-reader/scripts/README.md +45 -0
- package/vendor/ios-passport-reader/scripts/extract.py +197 -0
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
//
|
|
2
|
+
// OpenSSLUtils.swift
|
|
3
|
+
// NFCPassportReader
|
|
4
|
+
//
|
|
5
|
+
// Created by Andy Qua on 29/10/2019.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import OSLog
|
|
10
|
+
import OpenSSL
|
|
11
|
+
import CryptoTokenKit
|
|
12
|
+
|
|
13
|
+
@available(iOS 13, macOS 10.15, *)
|
|
14
|
+
public class OpenSSLUtils {
|
|
15
|
+
private static var loaded = false
|
|
16
|
+
|
|
17
|
+
/// Returns any OpenSSL Error as a String
|
|
18
|
+
public static func getOpenSSLError() -> String {
|
|
19
|
+
|
|
20
|
+
guard let out = BIO_new(BIO_s_mem()) else { return "Unknown" }
|
|
21
|
+
defer { BIO_free(out) }
|
|
22
|
+
|
|
23
|
+
ERR_print_errors( out )
|
|
24
|
+
let str = OpenSSLUtils.bioToString( bio:out )
|
|
25
|
+
|
|
26
|
+
return str
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// Extracts the contents of a BIO object and returns it as a String
|
|
30
|
+
/// - Parameter bio: a Pointer to a BIO buffer
|
|
31
|
+
/// - Returns: A string containing the contents of the BIO buffer
|
|
32
|
+
static func bioToString( bio : OpaquePointer ) -> String {
|
|
33
|
+
|
|
34
|
+
let len = BIO_ctrl(bio, BIO_CTRL_PENDING, 0, nil)
|
|
35
|
+
var buffer = [CChar](repeating: 0, count: len+1)
|
|
36
|
+
BIO_read(bio, &buffer, Int32(len))
|
|
37
|
+
|
|
38
|
+
// Ensure last value is 0 (null terminated) otherwise we get buffer overflow!
|
|
39
|
+
buffer[len] = 0
|
|
40
|
+
let ret = String(cString:buffer)
|
|
41
|
+
return ret
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static func X509ToPEM( x509: OpaquePointer ) -> String {
|
|
45
|
+
|
|
46
|
+
let out = BIO_new(BIO_s_mem())!
|
|
47
|
+
defer { BIO_free( out) }
|
|
48
|
+
|
|
49
|
+
PEM_write_bio_X509(out, x509);
|
|
50
|
+
let str = OpenSSLUtils.bioToString( bio:out )
|
|
51
|
+
|
|
52
|
+
return str
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static func pubKeyToPEM( pubKey: OpaquePointer ) -> String {
|
|
56
|
+
|
|
57
|
+
let out = BIO_new(BIO_s_mem())!
|
|
58
|
+
defer { BIO_free( out) }
|
|
59
|
+
|
|
60
|
+
PEM_write_bio_PUBKEY(out, pubKey);
|
|
61
|
+
let str = OpenSSLUtils.bioToString( bio:out )
|
|
62
|
+
|
|
63
|
+
return str
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static func privKeyToPEM( privKey: OpaquePointer ) -> String {
|
|
67
|
+
|
|
68
|
+
let out = BIO_new(BIO_s_mem())!
|
|
69
|
+
defer { BIO_free( out) }
|
|
70
|
+
|
|
71
|
+
PEM_write_bio_PrivateKey(out, privKey, nil, nil, 0, nil, nil)
|
|
72
|
+
let str = OpenSSLUtils.bioToString( bio:out )
|
|
73
|
+
|
|
74
|
+
return str
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static func pkcs7DataToPEM( pkcs7: Data ) -> String {
|
|
78
|
+
|
|
79
|
+
let inf = BIO_new(BIO_s_mem())!
|
|
80
|
+
defer { BIO_free( inf) }
|
|
81
|
+
let out = BIO_new(BIO_s_mem())!
|
|
82
|
+
defer { BIO_free( out) }
|
|
83
|
+
|
|
84
|
+
let _ = pkcs7.withUnsafeBytes { (ptr) in
|
|
85
|
+
BIO_write(inf, ptr.baseAddress?.assumingMemoryBound(to: Int8.self), Int32(pkcs7.count))
|
|
86
|
+
}
|
|
87
|
+
guard let p7 = d2i_PKCS7_bio(inf, nil) else { return "" }
|
|
88
|
+
defer { PKCS7_free(p7) }
|
|
89
|
+
|
|
90
|
+
PEM_write_bio_PKCS7(out, p7)
|
|
91
|
+
let str = OpenSSLUtils.bioToString( bio:out )
|
|
92
|
+
return str
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
/// Extracts a X509 certificate in PEM format from a PKCS7 container
|
|
97
|
+
/// - Parameter pkcs7Der: The PKCS7 container in DER format
|
|
98
|
+
/// - Returns: The PEM formatted X509 certificate
|
|
99
|
+
/// - Throws: A OpenSSLError.UnableToGetX509CertificateFromPKCS7 are thrown for any error
|
|
100
|
+
static func getX509CertificatesFromPKCS7( pkcs7Der : Data ) throws -> [X509Wrapper] {
|
|
101
|
+
|
|
102
|
+
guard let inf = BIO_new(BIO_s_mem()) else { throw OpenSSLError.UnableToGetX509CertificateFromPKCS7("Unable to allocate input buffer") }
|
|
103
|
+
defer { BIO_free(inf) }
|
|
104
|
+
let _ = pkcs7Der.withUnsafeBytes { (ptr) in
|
|
105
|
+
BIO_write(inf, ptr.baseAddress?.assumingMemoryBound(to: Int8.self), Int32(pkcs7Der.count))
|
|
106
|
+
}
|
|
107
|
+
guard let p7 = d2i_PKCS7_bio(inf, nil) else { throw OpenSSLError.UnableToGetX509CertificateFromPKCS7("Unable to read PKCS7 DER data") }
|
|
108
|
+
defer { PKCS7_free(p7) }
|
|
109
|
+
|
|
110
|
+
var certs : OpaquePointer? = nil
|
|
111
|
+
let i = OBJ_obj2nid(p7.pointee.type);
|
|
112
|
+
switch (i) {
|
|
113
|
+
case NID_pkcs7_signed:
|
|
114
|
+
if let sign = p7.pointee.d.sign {
|
|
115
|
+
certs = sign.pointee.cert
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
case NID_pkcs7_signedAndEnveloped:
|
|
119
|
+
if let signed_and_enveloped = p7.pointee.d.signed_and_enveloped {
|
|
120
|
+
certs = signed_and_enveloped.pointee.cert
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
default:
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
var ret = [X509Wrapper]()
|
|
128
|
+
if let certs = certs {
|
|
129
|
+
let certCount = sk_X509_num(certs)
|
|
130
|
+
for i in 0 ..< certCount {
|
|
131
|
+
let x = sk_X509_value(certs, i);
|
|
132
|
+
if let x509 = X509Wrapper(with:x) {
|
|
133
|
+
ret.append( x509 )
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return ret
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/// Checks whether a trust chain can be built up to verify a X509 certificate. A CAFile containing a list of trusted certificates (each in PEM format)
|
|
142
|
+
/// is used to build the trust chain.
|
|
143
|
+
/// The trusted certificates in this use case are typically from a Countries master list (see the scripts for more informaton on how to prepare this)
|
|
144
|
+
/// - Parameter x509Cert: The X509 certificate (in PEM format) to verify
|
|
145
|
+
/// - Parameter CAFile: The URL path of a file containing the list of certificates used to try to discover and build a trust chain
|
|
146
|
+
/// - Returns: either the X509 issue signing certificate that was used to sign the passed in X509 certificate or an error
|
|
147
|
+
static func verifyTrustAndGetIssuerCertificate( x509 : X509Wrapper, CAFile : URL ) -> Result<X509Wrapper, OpenSSLError> {
|
|
148
|
+
|
|
149
|
+
guard let cert_ctx = X509_STORE_new() else { return .failure(OpenSSLError.UnableToVerifyX509CertificateForSOD("Unable to create certificate store")) }
|
|
150
|
+
defer { X509_STORE_free(cert_ctx) }
|
|
151
|
+
|
|
152
|
+
X509_STORE_set_verify_cb(cert_ctx) { (ok, ctx) -> Int32 in
|
|
153
|
+
let cert_error = X509_STORE_CTX_get_error(ctx)
|
|
154
|
+
|
|
155
|
+
if ok == 0 {
|
|
156
|
+
let errVal = X509_verify_cert_error_string(Int(cert_error))
|
|
157
|
+
let val = errVal!.withMemoryRebound(to: CChar.self, capacity: 1000) { (ptr) in
|
|
158
|
+
return String(cString: ptr)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
Logger.openSSL.error("error \(cert_error) at \(X509_STORE_CTX_get_error_depth(ctx)) depth lookup:\(val)" )
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return ok;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
guard let lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()) else { return .failure(OpenSSLError.UnableToVerifyX509CertificateForSOD("Unable to add lookup to store")) }
|
|
168
|
+
|
|
169
|
+
// Load masterList.pem file
|
|
170
|
+
var rc = X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, CAFile.path, Int(X509_FILETYPE_PEM), nil)
|
|
171
|
+
|
|
172
|
+
guard let store = X509_STORE_CTX_new() else {
|
|
173
|
+
return .failure(OpenSSLError.UnableToVerifyX509CertificateForSOD("Unable to create new X509_STORE_CTX"))
|
|
174
|
+
}
|
|
175
|
+
defer { X509_STORE_CTX_free(store) }
|
|
176
|
+
|
|
177
|
+
X509_STORE_set_flags(cert_ctx, 0)
|
|
178
|
+
rc = X509_STORE_CTX_init(store, cert_ctx, x509.cert, nil)
|
|
179
|
+
if rc == 0 {
|
|
180
|
+
return .failure(OpenSSLError.UnableToVerifyX509CertificateForSOD("Unable to initialise X509_STORE_CTX"))
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// discover and verify X509 certificte chain
|
|
184
|
+
let i = X509_verify_cert(store);
|
|
185
|
+
if i != 1 {
|
|
186
|
+
let err = X509_STORE_CTX_get_error(store)
|
|
187
|
+
|
|
188
|
+
return .failure(OpenSSLError.UnableToVerifyX509CertificateForSOD("Verification of certificate failed - errorCode \(err)"))
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Get chain and issue certificate is the last cert in the chain
|
|
192
|
+
let chain = X509_STORE_CTX_get1_chain(store);
|
|
193
|
+
let nrCertsInChain = sk_X509_num(chain)
|
|
194
|
+
if nrCertsInChain > 1 {
|
|
195
|
+
let cert = sk_X509_value(chain, nrCertsInChain-1)
|
|
196
|
+
if let certWrapper = X509Wrapper(with: cert) {
|
|
197
|
+
return .success( certWrapper )
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return .failure(OpenSSLError.UnableToVerifyX509CertificateForSOD("Unable to get issuer certificate - not found"))
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
/// Verifies the signed data section against the stored certificate and extracts the signed data section from a PKCS7 container (if present and valid)
|
|
206
|
+
/// - Parameter pkcs7Der: The PKCS7 container in DER format
|
|
207
|
+
/// - Returns: The signed data from a PKCS7 container if we could read it
|
|
208
|
+
///
|
|
209
|
+
/// - Note: To test from the command line using openssl (NOTE NOT THE default mac version as it doesn't currently support CMS):
|
|
210
|
+
/// extract the SOD Base64 from an exported passport (you will need to unescape slashes!) - save this to ppt.b64
|
|
211
|
+
/// convert to binary (cat ppt.b64 | base64 -D > ppt.bin
|
|
212
|
+
/// extract the der file from the SOD (which includes header) - tail -c+5 ppt.bin > aq.der (blindy discards header)
|
|
213
|
+
/// convert der to PEM - openssl pkcs7 -in ppt.der --inform der -out ppt.pem -outform pem
|
|
214
|
+
/// verify signature data against included document signing cert - openssl cms -verify -in ppt.pem -inform pem -noverify
|
|
215
|
+
/// the -noverify is don't verify against the signers certifcate (as we don' thave that!)
|
|
216
|
+
///
|
|
217
|
+
/// This should return Verification Successful and the signed data
|
|
218
|
+
static func verifyAndReturnSODEncapsulatedDataUsingCMS( sod : SOD ) throws -> Data {
|
|
219
|
+
|
|
220
|
+
guard let inf = BIO_new(BIO_s_mem()) else { throw OpenSSLError.VerifyAndReturnSODEncapsulatedData("CMS - Unable to allocate input buffer") }
|
|
221
|
+
defer { BIO_free(inf) }
|
|
222
|
+
|
|
223
|
+
guard let out = BIO_new(BIO_s_mem()) else { throw OpenSSLError.VerifyAndReturnSODEncapsulatedData("CMS - Unable to allocate output buffer") }
|
|
224
|
+
defer { BIO_free(out) }
|
|
225
|
+
|
|
226
|
+
let _ = sod.body.withUnsafeBytes { (ptr) in
|
|
227
|
+
BIO_write(inf, ptr.baseAddress?.assumingMemoryBound(to: UInt8.self), Int32(sod.body.count))
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
guard let cms = d2i_CMS_bio(inf, nil) else {
|
|
231
|
+
throw OpenSSLError.VerifyAndReturnSODEncapsulatedData("CMS - Verification of P7 failed - unable to create CMS")
|
|
232
|
+
}
|
|
233
|
+
defer { CMS_ContentInfo_free(cms) }
|
|
234
|
+
|
|
235
|
+
let flags : UInt32 = UInt32(CMS_NO_SIGNER_CERT_VERIFY)
|
|
236
|
+
|
|
237
|
+
if CMS_verify(cms, nil, nil, nil, out, flags) == 0 {
|
|
238
|
+
throw OpenSSLError.VerifyAndReturnSODEncapsulatedData("CMS - Verification of P7 failed - unable to verify signature")
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
Logger.openSSL.debug("Verification successful\n");
|
|
242
|
+
let len = BIO_ctrl(out, BIO_CTRL_PENDING, 0, nil)
|
|
243
|
+
var buffer = [UInt8](repeating: 0, count: len)
|
|
244
|
+
BIO_read(out, &buffer, Int32(len))
|
|
245
|
+
let sigData = Data(buffer)
|
|
246
|
+
|
|
247
|
+
return sigData
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
static func verifyAndReturnSODEncapsulatedData( sod : SOD ) throws -> Data {
|
|
252
|
+
|
|
253
|
+
let encapsulatedContent = try sod.getEncapsulatedContent()
|
|
254
|
+
let signedAttribsHashAlgo = try sod.getEncapsulatedContentDigestAlgorithm()
|
|
255
|
+
let signedAttributes = try sod.getSignedAttributes()
|
|
256
|
+
let messageDigest = try sod.getMessageDigestFromSignedAttributes()
|
|
257
|
+
let signature = try sod.getSignature()
|
|
258
|
+
let sigType = try sod.getSignatureAlgorithm()
|
|
259
|
+
|
|
260
|
+
let pubKey = try sod.getPublicKey()
|
|
261
|
+
|
|
262
|
+
let mdHash : Data = try Data(calcHash(data: [UInt8](encapsulatedContent), hashAlgorithm: signedAttribsHashAlgo))
|
|
263
|
+
|
|
264
|
+
// Make sure that hash equals the messageDigest
|
|
265
|
+
if messageDigest != mdHash {
|
|
266
|
+
// Invalid - signed data hash doesn't match message digest hash
|
|
267
|
+
throw OpenSSLError.VerifyAndReturnSODEncapsulatedData("messageDigest Hash doesn't hatch that of the signed attributes")
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Verify signed attributes
|
|
271
|
+
if !verifySignature( data : [UInt8](signedAttributes), signature : [UInt8](signature), pubKey : pubKey, digestType: sigType ) {
|
|
272
|
+
|
|
273
|
+
throw OpenSSLError.VerifyAndReturnSODEncapsulatedData("Unable to verify signature for signed attributes")
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return encapsulatedContent
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/// Parses a signed data structures encoded in ASN1 format and returns the structure in text format
|
|
280
|
+
/// - Parameter data: The data to be parsed in ASN1 format
|
|
281
|
+
/// - Returns: The parsed data as A String
|
|
282
|
+
static func ASN1Parse( data: Data ) throws -> String {
|
|
283
|
+
|
|
284
|
+
guard let out = BIO_new(BIO_s_mem()) else { throw OpenSSLError.UnableToParseASN1("Unable to allocate output buffer") }
|
|
285
|
+
defer { BIO_free(out) }
|
|
286
|
+
|
|
287
|
+
var parsed : String = ""
|
|
288
|
+
let _ = try data.withUnsafeBytes { (ptr) in
|
|
289
|
+
let rc = ASN1_parse_dump(out, ptr.baseAddress?.assumingMemoryBound(to: UInt8.self), data.count, 0, 0)
|
|
290
|
+
if rc == 0 {
|
|
291
|
+
let str = OpenSSLUtils.getOpenSSLError()
|
|
292
|
+
Logger.openSSL.debug( "Failed to parse ASN1 Data - \(str)" )
|
|
293
|
+
throw OpenSSLError.UnableToParseASN1("Failed to parse ASN1 Data - \(str)")
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
parsed = bioToString(bio: out)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return parsed
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
/// Reads an RSA Public Key in DER format and converts it to an OpenSSL EVP_PKEY value for use whilst decrypting or verifying an RSA signature
|
|
305
|
+
/// - Parameter data: The RSA key in DER format
|
|
306
|
+
/// - Returns: The EVP_PKEY value
|
|
307
|
+
/// NOTE THE CALLER IS RESPONSIBLE FOR FREEING THE RETURNED KEY USING
|
|
308
|
+
/// EVP_PKEY_free(pemKey);
|
|
309
|
+
static func readRSAPublicKey( data : [UInt8] ) throws -> OpaquePointer? {
|
|
310
|
+
|
|
311
|
+
guard let inf = BIO_new(BIO_s_mem()) else { throw OpenSSLError.UnableToReadECPublicKey("Unable to allocate output buffer") }
|
|
312
|
+
defer { BIO_free(inf) }
|
|
313
|
+
|
|
314
|
+
let _ = data.withUnsafeBytes { (ptr) in
|
|
315
|
+
BIO_write(inf, ptr.baseAddress?.assumingMemoryBound(to: UInt8.self), Int32(data.count))
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
guard let rsakey = d2i_RSA_PUBKEY_bio(inf, nil) else { throw OpenSSLError.UnableToReadECPublicKey("Failed to load") }
|
|
319
|
+
defer{ RSA_free(rsakey) }
|
|
320
|
+
|
|
321
|
+
let key = EVP_PKEY_new()
|
|
322
|
+
if EVP_PKEY_set1_RSA(key, rsakey) != 1 {
|
|
323
|
+
EVP_PKEY_free(key)
|
|
324
|
+
throw OpenSSLError.UnableToReadECPublicKey("Failed to load")
|
|
325
|
+
}
|
|
326
|
+
return key
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/// This code is taken pretty much from rsautl.c - to decrypt a signature with a public key
|
|
330
|
+
/// NOTE: Current no padding is used! - This seems to be the default for Active Authentication RSA signatures (guess)
|
|
331
|
+
/// - Parameter signature: The RSA encrypted signature to decrypt
|
|
332
|
+
/// - Parameter pubKey: The RSA Public Key
|
|
333
|
+
/// - Returns: The decrypted signature data
|
|
334
|
+
static func decryptRSASignature( signature : Data, pubKey : OpaquePointer ) throws -> [UInt8] {
|
|
335
|
+
|
|
336
|
+
let pad = RSA_NO_PADDING
|
|
337
|
+
let rsa = EVP_PKEY_get1_RSA( pubKey )
|
|
338
|
+
|
|
339
|
+
let keysize = RSA_size(rsa);
|
|
340
|
+
var outputBuf = [UInt8](repeating: 0, count: Int(keysize))
|
|
341
|
+
|
|
342
|
+
// Decrypt signature
|
|
343
|
+
var outlen : Int32 = 0
|
|
344
|
+
let _ = signature.withUnsafeBytes { (sigPtr) in
|
|
345
|
+
let _ = outputBuf.withUnsafeMutableBytes { (outPtr) in
|
|
346
|
+
outlen = RSA_public_decrypt(Int32(signature.count), sigPtr.baseAddress?.assumingMemoryBound(to: UInt8.self), outPtr.baseAddress?.assumingMemoryBound(to: UInt8.self), rsa, pad)
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if outlen == 0 {
|
|
351
|
+
let error = OpenSSLUtils.getOpenSSLError()
|
|
352
|
+
throw OpenSSLError.UnableToDecryptRSASignature( "RSA_public_decrypt failed - \(error)" )
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return outputBuf
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/// Reads an ECDSA Public Key in DER format and converts it to an OpenSSL EVP_PKEY value for use whilst verifying a ECDSA signature
|
|
359
|
+
/// - Parameter data: The ECDSA key in DER forma
|
|
360
|
+
/// - Returns: The EVP_PKEY value
|
|
361
|
+
/// NOTE THE CALLER IS RESPONSIBLE FOR FREEING THE RETURNED KEY USING
|
|
362
|
+
/// EVP_PKEY_free(pemKey);
|
|
363
|
+
static func readECPublicKey( data : [UInt8] ) throws -> OpaquePointer? {
|
|
364
|
+
|
|
365
|
+
guard let inf = BIO_new(BIO_s_mem()) else { throw OpenSSLError.UnableToReadECPublicKey("Unable to allocate output buffer") }
|
|
366
|
+
defer { BIO_free(inf) }
|
|
367
|
+
|
|
368
|
+
let _ = data.withUnsafeBytes { (ptr) in
|
|
369
|
+
BIO_write(inf, ptr.baseAddress?.assumingMemoryBound(to: UInt8.self), Int32(data.count))
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
guard let eckey = d2i_EC_PUBKEY_bio(inf, nil) else { throw OpenSSLError.UnableToReadECPublicKey("Failed to load") }
|
|
373
|
+
defer{ EC_KEY_free(eckey) }
|
|
374
|
+
|
|
375
|
+
guard let outf = BIO_new(BIO_s_mem()) else { throw OpenSSLError.UnableToReadECPublicKey("Unable to allocate output buffer") }
|
|
376
|
+
defer { BIO_free(outf) }
|
|
377
|
+
let _ = PEM_write_bio_EC_PUBKEY(outf, eckey);
|
|
378
|
+
let pemKey = PEM_read_bio_PUBKEY(outf, nil, nil, nil)
|
|
379
|
+
|
|
380
|
+
return pemKey
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
/// Verifies Active Authentication data valid against an ECDSA signature and ECDSA Public Key - used in Active Authentication
|
|
385
|
+
/// - Parameter publicKey: The OpenSSL EVP_PKEY ECDSA key
|
|
386
|
+
/// - Parameter signature: The ECDSA signature to verify
|
|
387
|
+
/// - Parameter data: The data used to generate the signature
|
|
388
|
+
/// - Returns: True if the signature was verified
|
|
389
|
+
static func verifyECDSASignature( publicKey:OpaquePointer, signature: [UInt8], data: [UInt8], digestType: String = "" ) -> Bool {
|
|
390
|
+
|
|
391
|
+
// We first need to convert the signature from PLAIN ECDSA to ASN1 DER encoded
|
|
392
|
+
let ecsig = ECDSA_SIG_new()
|
|
393
|
+
defer { ECDSA_SIG_free(ecsig) }
|
|
394
|
+
let sigData = signature
|
|
395
|
+
let l = sigData.count / 2
|
|
396
|
+
sigData.withUnsafeBufferPointer { (unsafeBufPtr) in
|
|
397
|
+
let unsafePointer = unsafeBufPtr.baseAddress!
|
|
398
|
+
let r = BN_bin2bn(unsafePointer, Int32(l), nil)
|
|
399
|
+
let s = BN_bin2bn((unsafePointer + l), Int32(l), nil)
|
|
400
|
+
ECDSA_SIG_set0(ecsig, r, s)
|
|
401
|
+
}
|
|
402
|
+
let sigSize = i2d_ECDSA_SIG(ecsig, nil)
|
|
403
|
+
var derBytes = [UInt8](repeating: 0, count: Int(sigSize))
|
|
404
|
+
derBytes.withUnsafeMutableBufferPointer { (unsafeBufPtr) in
|
|
405
|
+
var unsafePointer = unsafeBufPtr.baseAddress
|
|
406
|
+
let _ = i2d_ECDSA_SIG(ecsig, &unsafePointer)
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
let rc = verifySignature(data: data, signature: derBytes, pubKey: publicKey, digestType: digestType)
|
|
410
|
+
return rc
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/// Verifies that a signature is valid for some data and a Public Key
|
|
414
|
+
/// - Parameter data: The data used to generate the signature
|
|
415
|
+
/// - Parameter signature: The signature to verify
|
|
416
|
+
/// - Parameter publicKey: The OpenSSL EVP_PKEY key
|
|
417
|
+
/// - Parameter digestType: the type of hash to use (empty string to use no digest type)
|
|
418
|
+
/// - Returns: True if the signature was verified
|
|
419
|
+
static func verifySignature( data : [UInt8], signature : [UInt8], pubKey : OpaquePointer, digestType: String ) -> Bool {
|
|
420
|
+
|
|
421
|
+
var digest = "sha256"
|
|
422
|
+
let digestType = digestType.lowercased()
|
|
423
|
+
if digestType.contains( "sha1" ) {
|
|
424
|
+
digest = "sha1"
|
|
425
|
+
} else if digestType.contains( "sha224" ) {
|
|
426
|
+
digest = "sha224"
|
|
427
|
+
} else if digestType.contains( "sha256" ) || digestType.contains( "rsassapss" ) {
|
|
428
|
+
digest = "sha256"
|
|
429
|
+
} else if digestType.contains( "sha384" ) {
|
|
430
|
+
digest = "sha384"
|
|
431
|
+
} else if digestType.contains( "sha512" ) {
|
|
432
|
+
digest = "sha512"
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Fix for some invalid ECDSA based signatures
|
|
436
|
+
// An ECDSA signature comprises of a Sequence of 2 big integers (R & S) and the verification
|
|
437
|
+
// is a linear equation of these two integers, the data hash and the public key
|
|
438
|
+
// However, in some passports the encoding of the integers is incorrect and has a leading 00
|
|
439
|
+
// causing the verification to fail.
|
|
440
|
+
// So in this case, we check to see if it is actually a valid BigInteger, and if not, we remove the
|
|
441
|
+
// leading prefix, check again and if a valid big integer this time then we use this otherwise
|
|
442
|
+
// we keep the original value
|
|
443
|
+
// If we change any values then we re-generate the signature and use this
|
|
444
|
+
var fixedSignature = signature
|
|
445
|
+
if digestType.contains( "ecdsa" ) {
|
|
446
|
+
// Decode signature
|
|
447
|
+
if let sequence = TKBERTLVRecord(from:Data(signature)),
|
|
448
|
+
sequence.tag == 0x30,
|
|
449
|
+
var intRecords = TKBERTLVRecord.sequenceOfRecords(from: sequence.value),
|
|
450
|
+
intRecords.count == 2 {
|
|
451
|
+
|
|
452
|
+
var didFix = false
|
|
453
|
+
for (idx, rec) in intRecords.enumerated() {
|
|
454
|
+
// Only process if the first byte is a 0
|
|
455
|
+
if rec.value[0] != 0 {
|
|
456
|
+
continue
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// There is a feature in TKBERTLVRecord.sequenceOfRecords where the 2nd record.data call
|
|
460
|
+
// contains the data for the whole data not the actual record
|
|
461
|
+
// (reported as FB9077037)
|
|
462
|
+
// So for the moment, work aroud this and create a new record
|
|
463
|
+
let fixedRec = TKBERTLVRecord( tag: rec.tag, value: rec.value)
|
|
464
|
+
let data = [UInt8](fixedRec.data)
|
|
465
|
+
|
|
466
|
+
// Check to see if a valid Big Integer (we need the whole record including tag and length for the d2i_ASN1_INTEGER call)
|
|
467
|
+
data.withUnsafeBufferPointer { (ptr) in
|
|
468
|
+
var address = ptr.baseAddress
|
|
469
|
+
let v = d2i_ASN1_INTEGER(nil, &address, data.count)
|
|
470
|
+
defer { ASN1_INTEGER_free(v) }
|
|
471
|
+
if v == nil {
|
|
472
|
+
// Not a valid BigInteger, so remove the first value and try again
|
|
473
|
+
let newRec = TKBERTLVRecord( tag: rec.tag, value: rec.value[1...])
|
|
474
|
+
|
|
475
|
+
let data2 = [UInt8](newRec.data)
|
|
476
|
+
data2.withUnsafeBufferPointer { (ptr) in
|
|
477
|
+
var address = ptr.baseAddress
|
|
478
|
+
let v2 = d2i_ASN1_INTEGER(nil, &address, data2.count)
|
|
479
|
+
defer { ASN1_INTEGER_free(v2) }
|
|
480
|
+
if v2 != nil {
|
|
481
|
+
// OK, we have a valid BigInteger this time so replace the original
|
|
482
|
+
// record with the new one
|
|
483
|
+
intRecords[idx] = newRec
|
|
484
|
+
didFix = true
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// We only reencode if we changed any of the integers, otherwise assume they were actually
|
|
492
|
+
// correctly encoded
|
|
493
|
+
if didFix {
|
|
494
|
+
// re-encode
|
|
495
|
+
let newSequence = TKBERTLVRecord( tag: sequence.tag, records: intRecords)
|
|
496
|
+
fixedSignature = [UInt8](newSequence.data)
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
let md = EVP_get_digestbyname(digest)
|
|
502
|
+
|
|
503
|
+
let ctx = EVP_MD_CTX_new()
|
|
504
|
+
var pkey_ctx : OpaquePointer?
|
|
505
|
+
|
|
506
|
+
defer{ EVP_MD_CTX_free( ctx) }
|
|
507
|
+
|
|
508
|
+
var nRes = EVP_DigestVerifyInit(ctx, &pkey_ctx, md, nil, pubKey)
|
|
509
|
+
if ( nRes != 1 ) {
|
|
510
|
+
return false;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if digestType.contains( "rsassapss" ) {
|
|
514
|
+
EVP_PKEY_CTX_ctrl_str(pkey_ctx, "rsa_padding_mode", "pss" )
|
|
515
|
+
EVP_PKEY_CTX_ctrl_str(pkey_ctx, "rsa_pss_saltlen", "auto" )
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
nRes = EVP_DigestUpdate(ctx, data, data.count);
|
|
519
|
+
if ( nRes != 1 ) {
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
nRes = EVP_DigestVerifyFinal(ctx, fixedSignature, fixedSignature.count);
|
|
524
|
+
if (nRes != 1) {
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return true
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
@available(iOS 13, macOS 10.15, *)
|
|
532
|
+
static func generateAESCMAC( key: [UInt8], message : [UInt8] ) -> [UInt8] {
|
|
533
|
+
let ctx = CMAC_CTX_new();
|
|
534
|
+
defer { CMAC_CTX_free(ctx) }
|
|
535
|
+
var key = key
|
|
536
|
+
|
|
537
|
+
var mac = [UInt8](repeating: 0, count: 32)
|
|
538
|
+
var maclen : Int = 0
|
|
539
|
+
|
|
540
|
+
if key.count == 16 {
|
|
541
|
+
CMAC_Init(ctx, &key, key.count, EVP_aes_128_cbc(), nil)
|
|
542
|
+
} else if key.count == 24 {
|
|
543
|
+
CMAC_Init(ctx, &key, key.count, EVP_aes_192_cbc(), nil)
|
|
544
|
+
} else if key.count == 32 {
|
|
545
|
+
CMAC_Init(ctx, &key, key.count, EVP_aes_256_cbc(), nil)
|
|
546
|
+
}
|
|
547
|
+
CMAC_Update(ctx, message, message.count);
|
|
548
|
+
CMAC_Final(ctx, &mac, &maclen);
|
|
549
|
+
|
|
550
|
+
Logger.openSSL.debug( "aesMac - mac - \(binToHexRep(mac))" )
|
|
551
|
+
|
|
552
|
+
return [UInt8](mac[0..<maclen])
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
@available(iOS 13, macOS 10.15, *)
|
|
556
|
+
static func asn1EncodeOID (oid : String) -> [UInt8] {
|
|
557
|
+
|
|
558
|
+
let obj = OBJ_txt2obj( oid.cString(using: .utf8), 1)
|
|
559
|
+
let payloadLen = i2d_ASN1_OBJECT(obj, nil)
|
|
560
|
+
|
|
561
|
+
var data = [UInt8](repeating: 0, count: Int(payloadLen))
|
|
562
|
+
|
|
563
|
+
let _ = data.withUnsafeMutableBytes { (ptr) in
|
|
564
|
+
var newPtr = ptr.baseAddress?.assumingMemoryBound(to: UInt8.self)
|
|
565
|
+
_ = i2d_ASN1_OBJECT(obj, &newPtr)
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
return data
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
@available(iOS 13, macOS 10.15, *)
|
|
572
|
+
public static func getPublicKeyData(from key:OpaquePointer) -> [UInt8]? {
|
|
573
|
+
var data : [UInt8] = []
|
|
574
|
+
// Get Key type
|
|
575
|
+
let v = EVP_PKEY_base_id( key )
|
|
576
|
+
if v == EVP_PKEY_DH || v == EVP_PKEY_DHX {
|
|
577
|
+
guard let dh = EVP_PKEY_get0_DH(key) else {
|
|
578
|
+
return nil
|
|
579
|
+
}
|
|
580
|
+
var dhPubKey : OpaquePointer?
|
|
581
|
+
DH_get0_key(dh, &dhPubKey, nil)
|
|
582
|
+
|
|
583
|
+
let nrBytes = (BN_num_bits(dhPubKey)+7)/8
|
|
584
|
+
data = [UInt8](repeating: 0, count: Int(nrBytes))
|
|
585
|
+
_ = BN_bn2bin(dhPubKey, &data)
|
|
586
|
+
} else if v == EVP_PKEY_EC {
|
|
587
|
+
|
|
588
|
+
guard let ec = EVP_PKEY_get0_EC_KEY(key),
|
|
589
|
+
let ec_pub = EC_KEY_get0_public_key(ec),
|
|
590
|
+
let ec_group = EC_KEY_get0_group(ec) else {
|
|
591
|
+
return nil
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
let form = EC_KEY_get_conv_form(ec)
|
|
595
|
+
let len = EC_POINT_point2oct(ec_group, ec_pub, form, nil, 0, nil)
|
|
596
|
+
data = [UInt8](repeating: 0, count: Int(len))
|
|
597
|
+
if len == 0 {
|
|
598
|
+
return nil
|
|
599
|
+
}
|
|
600
|
+
_ = EC_POINT_point2oct(ec_group, ec_pub, form, &data, len, nil)
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
return data
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// Caller is responsible for freeing the key
|
|
607
|
+
@available(iOS 13, macOS 10.15, *)
|
|
608
|
+
public static func decodePublicKeyFromBytes(pubKeyData: [UInt8], params: OpaquePointer) -> OpaquePointer? {
|
|
609
|
+
var pubKey : OpaquePointer?
|
|
610
|
+
|
|
611
|
+
let keyType = EVP_PKEY_base_id( params )
|
|
612
|
+
if keyType == EVP_PKEY_DH || keyType == EVP_PKEY_DHX {
|
|
613
|
+
|
|
614
|
+
let dhKey = DH_new()
|
|
615
|
+
defer{ DH_free(dhKey) }
|
|
616
|
+
|
|
617
|
+
// We don't free this as its part of the key!
|
|
618
|
+
let bn = BN_bin2bn(pubKeyData, Int32(pubKeyData.count), nil)
|
|
619
|
+
DH_set0_key(dhKey, bn, nil)
|
|
620
|
+
|
|
621
|
+
pubKey = EVP_PKEY_new()
|
|
622
|
+
guard EVP_PKEY_set1_DH(pubKey, dhKey) == 1 else {
|
|
623
|
+
return nil
|
|
624
|
+
}
|
|
625
|
+
} else {
|
|
626
|
+
let ec = EVP_PKEY_get1_EC_KEY(params)
|
|
627
|
+
let group = EC_KEY_get0_group(ec);
|
|
628
|
+
let ecp = EC_POINT_new(group);
|
|
629
|
+
let key = EC_KEY_new();
|
|
630
|
+
defer {
|
|
631
|
+
EC_KEY_free(ec)
|
|
632
|
+
EC_POINT_free(ecp)
|
|
633
|
+
EC_KEY_free(key)
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// Read EC_Point from public key data
|
|
637
|
+
guard EC_POINT_oct2point(group, ecp, pubKeyData, pubKeyData.count, nil) == 1,
|
|
638
|
+
EC_KEY_set_group(key, group) == 1,
|
|
639
|
+
EC_KEY_set_public_key(key, ecp) == 1 else {
|
|
640
|
+
|
|
641
|
+
return nil
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
pubKey = EVP_PKEY_new()
|
|
645
|
+
guard EVP_PKEY_set1_EC_KEY(pubKey, key) == 1 else {
|
|
646
|
+
return nil
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
return pubKey
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
public static func computeSharedSecret( privateKeyPair: OpaquePointer, publicKey: OpaquePointer ) -> [UInt8] {
|
|
655
|
+
|
|
656
|
+
// Oddly it seems that we cant use EVP_PKEY stuff for DH as it uses DTX keys which OpenSSL doesn't quite handle right
|
|
657
|
+
// OR I'm misunderstanding something (which is more possible)
|
|
658
|
+
// Works fine though for ECDH keys
|
|
659
|
+
var secret : [UInt8]
|
|
660
|
+
let keyType = EVP_PKEY_base_id( privateKeyPair )
|
|
661
|
+
if keyType == EVP_PKEY_DH || keyType == EVP_PKEY_DHX {
|
|
662
|
+
// Get bn for public key
|
|
663
|
+
let dh = EVP_PKEY_get1_DH(privateKeyPair);
|
|
664
|
+
|
|
665
|
+
let dh_pub = EVP_PKEY_get1_DH(publicKey)
|
|
666
|
+
var bn = BN_new()
|
|
667
|
+
DH_get0_key( dh_pub, &bn, nil )
|
|
668
|
+
|
|
669
|
+
secret = [UInt8](repeating: 0, count: Int(DH_size(dh)))
|
|
670
|
+
let len = DH_compute_key(&secret, bn, dh);
|
|
671
|
+
|
|
672
|
+
Logger.openSSL.debug( "OpenSSLUtils.computeSharedSecret - DH secret len - \(len)" )
|
|
673
|
+
} else {
|
|
674
|
+
let ctx = EVP_PKEY_CTX_new(privateKeyPair, nil)
|
|
675
|
+
defer{ EVP_PKEY_CTX_free(ctx) }
|
|
676
|
+
|
|
677
|
+
if EVP_PKEY_derive_init(ctx) != 1 {
|
|
678
|
+
// error
|
|
679
|
+
Logger.openSSL.error( "ERROR - \(OpenSSLUtils.getOpenSSLError())" )
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Set the public key
|
|
683
|
+
if EVP_PKEY_derive_set_peer( ctx, publicKey ) != 1 {
|
|
684
|
+
// error
|
|
685
|
+
Logger.openSSL.error( "ERROR - \(OpenSSLUtils.getOpenSSLError())" )
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// get buffer length needed for shared secret
|
|
689
|
+
var keyLen = 0
|
|
690
|
+
if EVP_PKEY_derive(ctx, nil, &keyLen) != 1 {
|
|
691
|
+
// Error
|
|
692
|
+
Logger.openSSL.error( "ERROR - \(OpenSSLUtils.getOpenSSLError())" )
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// Derive the shared secret
|
|
696
|
+
secret = [UInt8](repeating: 0, count: keyLen)
|
|
697
|
+
if EVP_PKEY_derive(ctx, &secret, &keyLen) != 1 {
|
|
698
|
+
// Error
|
|
699
|
+
Logger.openSSL.error( "ERROR - \(OpenSSLUtils.getOpenSSLError())" )
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
return secret
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
}
|