@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,301 @@
|
|
|
1
|
+
//
|
|
2
|
+
// SecureMessaging.swift
|
|
3
|
+
// NFCTest
|
|
4
|
+
//
|
|
5
|
+
// Created by Andy Qua on 09/06/2019.
|
|
6
|
+
// Copyright © 2019 Andy Qua. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
import OSLog
|
|
11
|
+
|
|
12
|
+
public enum SecureMessagingSupportedAlgorithms {
|
|
13
|
+
case DES
|
|
14
|
+
case AES
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
#if !os(macOS)
|
|
18
|
+
import CoreNFC
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
/// This class implements the secure messaging protocol.
|
|
22
|
+
/// The class is a new layer that comes between the reader and the iso7816.
|
|
23
|
+
/// It gives a new transmit method that takes an APDU object formed by the iso7816 layer,
|
|
24
|
+
/// ciphers it following the doc9303 specification, sends the ciphered APDU to the reader
|
|
25
|
+
/// layer and returns the unciphered APDU.
|
|
26
|
+
@available(iOS 13, *)
|
|
27
|
+
public class SecureMessaging {
|
|
28
|
+
private var ksenc : [UInt8]
|
|
29
|
+
private var ksmac : [UInt8]
|
|
30
|
+
private var ssc : [UInt8]
|
|
31
|
+
private let algoName : SecureMessagingSupportedAlgorithms
|
|
32
|
+
private let padLength : Int
|
|
33
|
+
|
|
34
|
+
public init( encryptionAlgorithm : SecureMessagingSupportedAlgorithms = .DES, ksenc : [UInt8], ksmac : [UInt8], ssc : [UInt8]) {
|
|
35
|
+
self.ksenc = ksenc
|
|
36
|
+
self.ksmac = ksmac
|
|
37
|
+
self.ssc = ssc
|
|
38
|
+
self.algoName = encryptionAlgorithm
|
|
39
|
+
self.padLength = algoName == .DES ? 8 : 16
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/// Protect the apdu following the doc9303 specification
|
|
43
|
+
func protect(apdu : NFCISO7816APDU, useExtendedMode: Bool = false ) throws -> NFCISO7816APDU {
|
|
44
|
+
|
|
45
|
+
Logger.secureMessaging.debug("\t\tSSC: \(binToHexRep(self.ssc))")
|
|
46
|
+
self.ssc = self.incSSC()
|
|
47
|
+
let paddedSSC = algoName == .DES ? self.ssc : [UInt8](repeating: 0, count: 8) + ssc
|
|
48
|
+
Logger.secureMessaging.debug("\tIncrement SSC with 1")
|
|
49
|
+
Logger.secureMessaging.debug("\t\tSSC: \(binToHexRep(self.ssc))")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
let cmdHeader = self.maskClassAndPad(apdu: apdu)
|
|
53
|
+
var do87 : [UInt8] = []
|
|
54
|
+
var do97 : [UInt8] = []
|
|
55
|
+
|
|
56
|
+
var tmp = "Concatenate CmdHeader"
|
|
57
|
+
if apdu.data != nil {
|
|
58
|
+
tmp += " and DO87"
|
|
59
|
+
do87 = try self.buildD087(apdu: apdu)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let isMSE = apdu.instructionCode == 0x22
|
|
63
|
+
if apdu.expectedResponseLength > 0 && (isMSE ? apdu.expectedResponseLength < 256 : true) {
|
|
64
|
+
tmp += " and DO97"
|
|
65
|
+
do97 = try self.buildD097(apdu: apdu)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let M = cmdHeader + do87 + do97
|
|
69
|
+
Logger.secureMessaging.debug("\(tmp)")
|
|
70
|
+
Logger.secureMessaging.debug("\tM: \(binToHexRep(M))")
|
|
71
|
+
|
|
72
|
+
Logger.secureMessaging.debug("Compute MAC of M")
|
|
73
|
+
|
|
74
|
+
let N = pad(paddedSSC + M, blockSize:padLength)
|
|
75
|
+
Logger.secureMessaging.debug("\tConcatenate SSC and M and add padding")
|
|
76
|
+
Logger.secureMessaging.debug("\t\tN: \(binToHexRep(N))")
|
|
77
|
+
|
|
78
|
+
var CC = mac(algoName: algoName, key: self.ksmac, msg: N)
|
|
79
|
+
if CC.count > 8 {
|
|
80
|
+
CC = [UInt8](CC[0..<8])
|
|
81
|
+
}
|
|
82
|
+
Logger.secureMessaging.debug("\tCompute MAC over N with KSmac")
|
|
83
|
+
Logger.secureMessaging.debug("\t\tCC: \(binToHexRep(CC))")
|
|
84
|
+
|
|
85
|
+
let do8e = self.buildD08E(mac: CC)
|
|
86
|
+
|
|
87
|
+
// If dataSize > 255 then it will be encoded in 3 bytes with the first byte being 0x00
|
|
88
|
+
// otherwise its a single byte of size
|
|
89
|
+
let size = do87.count + do97.count + do8e.count
|
|
90
|
+
var dataSize: [UInt8]
|
|
91
|
+
if size > 255 || (useExtendedMode && apdu.expectedResponseLength > 231) {
|
|
92
|
+
dataSize = [0x00] + intToBin(size, pad: 4)
|
|
93
|
+
} else {
|
|
94
|
+
dataSize = intToBin(size)
|
|
95
|
+
}
|
|
96
|
+
var protectedAPDU = [UInt8](cmdHeader[0..<4]) + dataSize
|
|
97
|
+
protectedAPDU += do87 + do97 + do8e
|
|
98
|
+
|
|
99
|
+
// If the data is more that 255, specify the we are using extended length (0x00, 0x00)
|
|
100
|
+
// Thanks to @filom for the fix!
|
|
101
|
+
if size > 255 || (useExtendedMode && apdu.expectedResponseLength > 231) {
|
|
102
|
+
protectedAPDU += [0x00,0x00]
|
|
103
|
+
} else {
|
|
104
|
+
protectedAPDU += [0x00]
|
|
105
|
+
}
|
|
106
|
+
Logger.secureMessaging.debug("Construct and send protected APDU")
|
|
107
|
+
Logger.secureMessaging.debug("\tProtectedAPDU: \(binToHexRep(protectedAPDU))")
|
|
108
|
+
|
|
109
|
+
let newAPDU = NFCISO7816APDU(data:Data(protectedAPDU))!
|
|
110
|
+
return newAPDU
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/// Unprotect the APDU following the iso7816 specification
|
|
114
|
+
func unprotect(rapdu : ResponseAPDU ) throws -> ResponseAPDU {
|
|
115
|
+
var needCC = false
|
|
116
|
+
var do87 : [UInt8] = []
|
|
117
|
+
var do87Data : [UInt8] = []
|
|
118
|
+
var do99 : [UInt8] = []
|
|
119
|
+
//var do8e : [UInt8] = []
|
|
120
|
+
var offset = 0
|
|
121
|
+
|
|
122
|
+
self.ssc = self.incSSC()
|
|
123
|
+
let paddedSSC = algoName == .DES ? self.ssc : [UInt8](repeating: 0, count: 8) + ssc
|
|
124
|
+
Logger.secureMessaging.debug("\tIncrement SSC with 1")
|
|
125
|
+
Logger.secureMessaging.debug("\t\tSSC: \(binToHexRep(self.ssc))")
|
|
126
|
+
|
|
127
|
+
// Check for a SM error
|
|
128
|
+
if(rapdu.sw1 != 0x90 || rapdu.sw2 != 0x00) {
|
|
129
|
+
return rapdu
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
let rapduBin = rapdu.data + [rapdu.sw1, rapdu.sw2]
|
|
133
|
+
Logger.secureMessaging.debug("Receive response APDU of MRTD's chip")
|
|
134
|
+
Logger.secureMessaging.debug("\tRAPDU: \(binToHexRep(rapduBin))")
|
|
135
|
+
|
|
136
|
+
// DO'87'
|
|
137
|
+
// Mandatory if data is returned, otherwise absent
|
|
138
|
+
if rapduBin[0] == 0x87 {
|
|
139
|
+
let (encDataLength, o) = try asn1Length([UInt8](rapduBin[1...]))
|
|
140
|
+
offset = 1 + o
|
|
141
|
+
|
|
142
|
+
if rapduBin[offset] != 0x1 {
|
|
143
|
+
throw NFCPassportReaderError.D087Malformed
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
do87 = [UInt8](rapduBin[0 ..< offset + Int(encDataLength)])
|
|
147
|
+
do87Data = [UInt8](rapduBin[offset+1 ..< offset + Int(encDataLength)])
|
|
148
|
+
offset += Int(encDataLength)
|
|
149
|
+
needCC = true
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
//DO'99'
|
|
153
|
+
// Mandatory, only absent if SM error occurs
|
|
154
|
+
guard rapduBin.count >= offset + 5 else {
|
|
155
|
+
Logger.secureMessaging.error("size error")
|
|
156
|
+
let returnSw1 = (rapduBin.count >= offset+3) ? rapduBin[offset+2] : 0;
|
|
157
|
+
let returnSw2 = (rapduBin.count >= offset+4) ? rapduBin[offset+3] : 0;
|
|
158
|
+
return ResponseAPDU(data: [], sw1: returnSw1, sw2: returnSw2);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
do99 = [UInt8](rapduBin[offset..<offset+4])
|
|
162
|
+
let sw1 = rapduBin[offset+2]
|
|
163
|
+
let sw2 = rapduBin[offset+3]
|
|
164
|
+
offset += 4
|
|
165
|
+
needCC = true
|
|
166
|
+
|
|
167
|
+
if do99[0] != 0x99 && do99[1] != 0x02 {
|
|
168
|
+
//SM error, return the error code
|
|
169
|
+
return ResponseAPDU(data: [], sw1: sw1, sw2: sw2)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// DO'8E'
|
|
173
|
+
//Mandatory if DO'87' and/or DO'99' is present
|
|
174
|
+
if rapduBin[offset] == 0x8E {
|
|
175
|
+
let ccLength : Int = Int(binToHex(rapduBin[offset+1]))
|
|
176
|
+
let CC = [UInt8](rapduBin[offset+2 ..< offset+2+ccLength])
|
|
177
|
+
// do8e = [UInt8](rapduBin[offset ..< offset+2+ccLength])
|
|
178
|
+
|
|
179
|
+
// CheckCC
|
|
180
|
+
var tmp = ""
|
|
181
|
+
if do87.count > 0 {
|
|
182
|
+
tmp += " DO'87"
|
|
183
|
+
}
|
|
184
|
+
if do99.count > 0 {
|
|
185
|
+
tmp += " DO'99"
|
|
186
|
+
}
|
|
187
|
+
Logger.secureMessaging.debug("Verify RAPDU CC by computing MAC of \(tmp)")
|
|
188
|
+
|
|
189
|
+
let K = pad(paddedSSC + do87 + do99, blockSize:padLength)
|
|
190
|
+
Logger.secureMessaging.debug("\tConcatenate SSC and \(tmp) and add padding")
|
|
191
|
+
Logger.secureMessaging.debug("\t\tK: \(binToHexRep(K))")
|
|
192
|
+
|
|
193
|
+
Logger.secureMessaging.debug("\tCompute MAC with KSmac")
|
|
194
|
+
var CCb = mac(algoName: algoName, key: self.ksmac, msg: K)
|
|
195
|
+
if CCb.count > 8 {
|
|
196
|
+
CCb = [UInt8](CC[0..<8])
|
|
197
|
+
}
|
|
198
|
+
Logger.secureMessaging.debug("\t\tCC: \(binToHexRep(CCb))")
|
|
199
|
+
|
|
200
|
+
let res = (CC == CCb)
|
|
201
|
+
Logger.secureMessaging.debug("\tCompare CC with data of DO'8E of RAPDU")
|
|
202
|
+
Logger.secureMessaging.debug("\t\t\(binToHexRep(CC)) == \(binToHexRep(CCb)) ? \(res)")
|
|
203
|
+
|
|
204
|
+
if !res {
|
|
205
|
+
throw NFCPassportReaderError.InvalidResponseChecksum
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
else if needCC {
|
|
209
|
+
throw NFCPassportReaderError.MissingMandatoryFields
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
var data : [UInt8] = []
|
|
213
|
+
if do87Data.count > 0 {
|
|
214
|
+
|
|
215
|
+
let dec : [UInt8]
|
|
216
|
+
if algoName == .DES {
|
|
217
|
+
dec = tripleDESDecrypt(key: self.ksenc, message: do87Data, iv: [0,0,0,0,0,0,0,0])
|
|
218
|
+
} else {
|
|
219
|
+
// for AES the IV is the ssc with AES/EBC/NOPADDING
|
|
220
|
+
let paddedssc = [UInt8](repeating: 0, count: 8) + ssc
|
|
221
|
+
let iv = AESECBEncrypt(key: ksenc, message: paddedssc)
|
|
222
|
+
dec = AESDecrypt(key: self.ksenc, message: do87Data, iv: iv)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// There is a payload
|
|
226
|
+
data = unpad(dec)
|
|
227
|
+
Logger.secureMessaging.debug("Decrypt data of DO'87 with KSenc")
|
|
228
|
+
Logger.secureMessaging.debug("\tDecryptedData: \(binToHexRep(data))")
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
Logger.secureMessaging.debug("Unprotected APDU: [\(binToHexRep(data))] \(binToHexRep(sw1)) \(binToHexRep(sw2))" )
|
|
232
|
+
return ResponseAPDU(data: data, sw1: sw1, sw2: sw2)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
func maskClassAndPad(apdu : NFCISO7816APDU ) -> [UInt8] {
|
|
236
|
+
Logger.secureMessaging.debug("Mask class byte and pad command header")
|
|
237
|
+
let res = pad([0x0c, apdu.instructionCode, apdu.p1Parameter, apdu.p2Parameter], blockSize: padLength)
|
|
238
|
+
Logger.secureMessaging.debug("\tCmdHeader: \(binToHexRep(res))")
|
|
239
|
+
return res
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
func buildD087(apdu : NFCISO7816APDU) throws -> [UInt8] {
|
|
243
|
+
let cipher = [0x01] + self.padAndEncryptData(apdu)
|
|
244
|
+
let res = try [0x87] + toAsn1Length(cipher.count) + cipher
|
|
245
|
+
Logger.secureMessaging.debug("Build DO'87")
|
|
246
|
+
Logger.secureMessaging.debug("\tDO87: \(binToHexRep(res))")
|
|
247
|
+
return res
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
func padAndEncryptData(_ apdu : NFCISO7816APDU) -> [UInt8] {
|
|
251
|
+
// Pad the data, encrypt data with KSenc and build DO'87
|
|
252
|
+
let data = [UInt8](apdu.data!)
|
|
253
|
+
let paddedData = pad( data, blockSize: padLength )
|
|
254
|
+
|
|
255
|
+
let enc : [UInt8]
|
|
256
|
+
if algoName == .DES {
|
|
257
|
+
enc = tripleDESEncrypt(key: self.ksenc, message: paddedData, iv: [0,0,0,0,0,0,0,0])
|
|
258
|
+
} else {
|
|
259
|
+
// for AES the IV is the ssc with AES/EBC/NOPADDING
|
|
260
|
+
let paddedssc = [UInt8](repeating: 0, count: 8) + ssc
|
|
261
|
+
let iv = AESECBEncrypt(key: ksenc, message: paddedssc)
|
|
262
|
+
enc = AESEncrypt(key: self.ksenc, message: paddedData, iv: iv)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
Logger.secureMessaging.debug("Pad data")
|
|
266
|
+
Logger.secureMessaging.debug("\tData: \(binToHexRep(paddedData))")
|
|
267
|
+
Logger.secureMessaging.debug("Encrypt data with KSenc")
|
|
268
|
+
Logger.secureMessaging.debug("\tEncryptedData: \(binToHexRep(enc))")
|
|
269
|
+
return enc
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
func incSSC() -> [UInt8] {
|
|
273
|
+
let val = binToHex(self.ssc) + 1
|
|
274
|
+
|
|
275
|
+
// This needs to be fully zero padded - to 8 bytes = i.e. if SSC is 1 it should return [0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1]
|
|
276
|
+
// NOT [0x1]
|
|
277
|
+
return withUnsafeBytes(of: val.bigEndian, Array.init)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
func buildD08E(mac : [UInt8]) -> [UInt8] {
|
|
281
|
+
let res : [UInt8] = [0x8E, UInt8(mac.count)] + mac
|
|
282
|
+
Logger.secureMessaging.debug("Build DO'8E")
|
|
283
|
+
Logger.secureMessaging.debug("\tDO8E: \(binToHexRep(res))" )
|
|
284
|
+
return res
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
func buildD097(apdu : NFCISO7816APDU) throws -> [UInt8] {
|
|
288
|
+
let le = apdu.expectedResponseLength
|
|
289
|
+
var binLe = intToBin(le)
|
|
290
|
+
if (le == 256 || le == 65536) {
|
|
291
|
+
binLe = [0x00] + (le > 256 ? [0x00] : [])
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
let res : [UInt8] = try [0x97] + toAsn1Length(binLe.count) + binLe
|
|
295
|
+
Logger.secureMessaging.debug("Build DO'97")
|
|
296
|
+
Logger.secureMessaging.debug("\tDO97: \(res)")
|
|
297
|
+
return res
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
}
|
|
301
|
+
#endif
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
//
|
|
2
|
+
// SecureMessagingSessionKeyGenerator.swift
|
|
3
|
+
// NFCPassportReader
|
|
4
|
+
//
|
|
5
|
+
// Created by Andy Qua on 25/02/2021.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
import CryptoKit
|
|
11
|
+
|
|
12
|
+
@available(iOS 13, macOS 10.15, *)
|
|
13
|
+
class SecureMessagingSessionKeyGenerator {
|
|
14
|
+
static let NO_PACE_KEY_REFERENCE : UInt8 = 0x00
|
|
15
|
+
enum SMSMode : UInt8 {
|
|
16
|
+
case ENC_MODE = 0x1;
|
|
17
|
+
case MAC_MODE = 0x2;
|
|
18
|
+
case PACE_MODE = 0x3;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// Derives the ENC or MAC key for BAC from the keySeed.
|
|
22
|
+
/// - Parameter keySeed the key seed.
|
|
23
|
+
/// - Parameter mode either <code>ENC_MODE</code> or <code>MAC_MODE</code>
|
|
24
|
+
/// - Returns the key.
|
|
25
|
+
/// - Throws InvalidDataPassed on data error
|
|
26
|
+
func deriveKey( keySeed : [UInt8], mode : SMSMode) throws -> [UInt8] {
|
|
27
|
+
return try deriveKey(keySeed: keySeed, cipherAlgName: "DESede", keyLength: 128, mode: mode);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/// Derives the ENC or MAC key for BAC or PACE or CA.
|
|
31
|
+
/// - Parameter keySeed the key seed.
|
|
32
|
+
/// - Parameter cipherAlgName either AES or DESede
|
|
33
|
+
/// - Parameter keyLength key length in bits
|
|
34
|
+
/// - Parameter mode either {@code ENC_MODE}, {@code MAC_MODE}, or {@code PACE_MODE}
|
|
35
|
+
/// - Returns the key.
|
|
36
|
+
/// - Throws InvalidDataPassed on data error
|
|
37
|
+
func deriveKey(keySeed : [UInt8], cipherAlgName :String, keyLength : Int, mode : SMSMode) throws -> [UInt8] {
|
|
38
|
+
return try deriveKey(keySeed: keySeed, cipherAlgName: cipherAlgName, keyLength: keyLength, nonce: nil, mode: mode);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// Derives the ENC or MAC key for BAC or PACE or CA.
|
|
42
|
+
/// - Parameter keySeed the shared secret, as octets
|
|
43
|
+
/// - Parameter cipherAlg in Java mnemonic notation (for example "DESede", "AES")
|
|
44
|
+
/// - Parameter keyLength length in bits
|
|
45
|
+
/// - Parameter nonce optional nonce or <code>nil</code>
|
|
46
|
+
/// - Parameter mode the mode either {@code ENC}, {@code MAC}, or {@code PACE} mode
|
|
47
|
+
/// - Returns the key.
|
|
48
|
+
/// - Throws InvalidDataPassed on data error
|
|
49
|
+
func deriveKey(keySeed : [UInt8], cipherAlgName :String, keyLength : Int, nonce : [UInt8]? = nil, mode : SMSMode) throws -> [UInt8] {
|
|
50
|
+
return try deriveKey(keySeed: keySeed, cipherAlgName: cipherAlgName, keyLength: keyLength, nonce: nonce, mode: mode, paceKeyReference: SecureMessagingSessionKeyGenerator.NO_PACE_KEY_REFERENCE);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/// Derives the ENC or MAC key for BAC or PACE or CA.
|
|
54
|
+
/// - Parameter keySeed the shared secret, as octets
|
|
55
|
+
/// - Parameter cipherAlg in Java mnemonic notation (for example "DESede", "AES")
|
|
56
|
+
/// - Parameter keyLength length in bits
|
|
57
|
+
/// - Parameter nonce optional nonce or <code>null</code>
|
|
58
|
+
/// - Parameter mode the mode either {@code ENC}, {@code MAC}, or {@code PACE} mode
|
|
59
|
+
/// - Parameter paceKeyReference Key Reference For Pace Protocol
|
|
60
|
+
/// - Returns the key.
|
|
61
|
+
/// - Throws InvalidDataPassed on data error
|
|
62
|
+
func deriveKey(keySeed : [UInt8], cipherAlgName :String, keyLength : Int, nonce : [UInt8]?, mode : SMSMode, paceKeyReference : UInt8) throws -> [UInt8] {
|
|
63
|
+
let digestAlgo = try inferDigestAlgorithmFromCipherAlgorithmForKeyDerivation(cipherAlg: cipherAlgName, keyLength: keyLength);
|
|
64
|
+
|
|
65
|
+
let modeArr : [UInt8] = [0x00, 0x00, 0x00, mode.rawValue]
|
|
66
|
+
var dataEls = [Data(keySeed)]
|
|
67
|
+
if let nonce = nonce {
|
|
68
|
+
dataEls.append( Data(nonce) )
|
|
69
|
+
}
|
|
70
|
+
dataEls.append( Data(modeArr) )
|
|
71
|
+
let hashResult = try getHash(algo: digestAlgo, dataElements: dataEls)
|
|
72
|
+
|
|
73
|
+
var keyBytes : [UInt8]
|
|
74
|
+
if cipherAlgName == "DESede" || cipherAlgName == "3DES" {
|
|
75
|
+
// TR-SAC 1.01, 4.2.1.
|
|
76
|
+
switch(keyLength) {
|
|
77
|
+
case 112, 128:
|
|
78
|
+
// Copy E (Octects 1 to 8), D (Octects 9 to 16), E (again Octects 1 to 8), 112-bit 3DES key
|
|
79
|
+
keyBytes = [UInt8](hashResult[0..<16] + hashResult[0..<8])
|
|
80
|
+
break;
|
|
81
|
+
default:
|
|
82
|
+
throw NFCPassportReaderError.InvalidDataPassed("Can only use DESede with 128-but key length")
|
|
83
|
+
}
|
|
84
|
+
} else if cipherAlgName.lowercased() == "aes" || cipherAlgName.lowercased().hasPrefix("aes") {
|
|
85
|
+
// TR-SAC 1.01, 4.2.2.
|
|
86
|
+
switch(keyLength) {
|
|
87
|
+
case 128:
|
|
88
|
+
keyBytes = [UInt8](hashResult[0..<16]) // NOTE: 128 = 16 * 8
|
|
89
|
+
case 192:
|
|
90
|
+
keyBytes = [UInt8](hashResult[0..<24]) // NOTE: 192 = 24 * 8
|
|
91
|
+
case 256:
|
|
92
|
+
keyBytes = [UInt8](hashResult[0..<32]) // NOTE: 256 = 32 * 8
|
|
93
|
+
default:
|
|
94
|
+
throw NFCPassportReaderError.InvalidDataPassed("Can only use AES with 128-bit, 192-bit key or 256-bit length")
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
throw NFCPassportReaderError.InvalidDataPassed( "Unsupported cipher algorithm used" )
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return keyBytes
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
func inferDigestAlgorithmFromCipherAlgorithmForKeyDerivation( cipherAlg : String, keyLength : Int) throws -> String {
|
|
104
|
+
if cipherAlg == "DESede" || cipherAlg == "AES-128" {
|
|
105
|
+
return "SHA1";
|
|
106
|
+
}
|
|
107
|
+
if cipherAlg == "AES" && keyLength == 128 {
|
|
108
|
+
return "SHA1";
|
|
109
|
+
}
|
|
110
|
+
if cipherAlg == "AES-256" || cipherAlg == "AES-192" {
|
|
111
|
+
return "SHA256";
|
|
112
|
+
}
|
|
113
|
+
if cipherAlg == "AES" && (keyLength == 192 || keyLength == 256) {
|
|
114
|
+
return "SHA256";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
throw NFCPassportReaderError.InvalidDataPassed("Unsupported cipher algorithm or key length")
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/// This generates a SHA-X hash based on the passed in algo.
|
|
121
|
+
/// There must be a more generic way to do this?
|
|
122
|
+
func getHash(algo: String, dataElements:[Data] ) throws -> [UInt8] {
|
|
123
|
+
var hash : [UInt8]
|
|
124
|
+
|
|
125
|
+
let algo = algo.lowercased()
|
|
126
|
+
if algo == "sha1" {
|
|
127
|
+
var hasher = Insecure.SHA1()
|
|
128
|
+
for d in dataElements {
|
|
129
|
+
hasher.update( data:d )
|
|
130
|
+
}
|
|
131
|
+
hash = Array(hasher.finalize())
|
|
132
|
+
} else if algo == "sha256" {
|
|
133
|
+
var hasher = SHA256()
|
|
134
|
+
for d in dataElements {
|
|
135
|
+
hasher.update( data:d )
|
|
136
|
+
}
|
|
137
|
+
hash = Array(hasher.finalize())
|
|
138
|
+
} else if algo == "sha384" {
|
|
139
|
+
var hasher = SHA384()
|
|
140
|
+
for d in dataElements {
|
|
141
|
+
hasher.update( data:d )
|
|
142
|
+
}
|
|
143
|
+
hash = Array(hasher.finalize())
|
|
144
|
+
} else if algo == "sha512" {
|
|
145
|
+
var hasher = SHA512()
|
|
146
|
+
for d in dataElements {
|
|
147
|
+
hasher.update( data:d )
|
|
148
|
+
}
|
|
149
|
+
hash = Array(hasher.finalize())
|
|
150
|
+
} else {
|
|
151
|
+
throw NFCPassportReaderError.InvalidHashAlgorithmSpecified
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return hash
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
//
|
|
2
|
+
// SimpleASN1Parser.swift
|
|
3
|
+
// NFCPassportReader
|
|
4
|
+
//
|
|
5
|
+
// Created by Andy Qua on 25/01/2021.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import OpenSSL
|
|
10
|
+
|
|
11
|
+
@available(iOS 13, macOS 10.15, *)
|
|
12
|
+
public class ASN1Item : CustomDebugStringConvertible {
|
|
13
|
+
var pos : Int = -1
|
|
14
|
+
var depth : Int = -1
|
|
15
|
+
var headerLen : Int = -1
|
|
16
|
+
var length : Int = -1
|
|
17
|
+
var itemType : String = "" // Primative or Constructed (prim or cons)
|
|
18
|
+
var type : String = "" // Actual type of the value ( object, set, etc)
|
|
19
|
+
var value : String = ""
|
|
20
|
+
var line : String = ""
|
|
21
|
+
var parent : ASN1Item? = nil
|
|
22
|
+
|
|
23
|
+
private var children = [ASN1Item] ()
|
|
24
|
+
|
|
25
|
+
public init( line : String) {
|
|
26
|
+
self.line = line
|
|
27
|
+
|
|
28
|
+
let scanner = Scanner(string: line)
|
|
29
|
+
|
|
30
|
+
let space = CharacterSet(charactersIn: " =:")
|
|
31
|
+
let equals = CharacterSet(charactersIn: "= ")
|
|
32
|
+
let colon = CharacterSet(charactersIn: ":")
|
|
33
|
+
let end = CharacterSet(charactersIn: "\n")
|
|
34
|
+
|
|
35
|
+
scanner.charactersToBeSkipped = space
|
|
36
|
+
self.pos = scanner.scanInt() ?? -1
|
|
37
|
+
_ = scanner.scanUpToCharacters(from: equals)
|
|
38
|
+
self.depth = scanner.scanInt() ?? -1
|
|
39
|
+
_ = scanner.scanUpToCharacters(from: equals)
|
|
40
|
+
self.headerLen = scanner.scanInt() ?? -1
|
|
41
|
+
_ = scanner.scanUpToCharacters(from: equals)
|
|
42
|
+
self.length = scanner.scanInt() ?? -1
|
|
43
|
+
self.itemType = scanner.scanUpToCharacters(from: colon) ?? ""
|
|
44
|
+
let rest = scanner.scanUpToCharacters(from: end)?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
|
45
|
+
|
|
46
|
+
if itemType == "cons" {
|
|
47
|
+
type = rest
|
|
48
|
+
|
|
49
|
+
} else {
|
|
50
|
+
let items = rest.components(separatedBy: ":" ).filter{ !$0.isEmpty }
|
|
51
|
+
self.type = items[0].trimmingCharacters(in: .whitespacesAndNewlines)
|
|
52
|
+
if ( items.count > 1 ) {
|
|
53
|
+
self.value = items[1].trimmingCharacters(in: .whitespacesAndNewlines)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
func addChild( _ child : ASN1Item ) {
|
|
59
|
+
child.parent = self
|
|
60
|
+
self.children.append( child )
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public func getChild( _ child : Int ) -> ASN1Item? {
|
|
64
|
+
if ( child < children.count ) {
|
|
65
|
+
return children[child]
|
|
66
|
+
} else {
|
|
67
|
+
return nil
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public func getNumberOfChildren() -> Int {
|
|
72
|
+
return children.count
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public var debugDescription: String {
|
|
76
|
+
var ret = "pos:\(pos), d=\(depth), hl=\(headerLen), l=\(length): \(itemType): \(type) \(value)\n"
|
|
77
|
+
children.forEach { ret += $0.debugDescription }
|
|
78
|
+
return ret
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/// Very very basic ASN1 parser class - uses OpenSSL to dump an ASN1 structure to a string, and then parses that out into
|
|
83
|
+
/// a tree based hieracy of ASN1Item structures - depth based
|
|
84
|
+
@available(iOS 13, macOS 10.15, *)
|
|
85
|
+
public class SimpleASN1DumpParser {
|
|
86
|
+
public init() {
|
|
87
|
+
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public func parse( data: Data ) throws -> ASN1Item {
|
|
91
|
+
var parsed : String = ""
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
let _ = try data.withUnsafeBytes { (ptr) in
|
|
95
|
+
guard let out = BIO_new(BIO_s_mem()) else { throw OpenSSLError.UnableToParseASN1("Unable to allocate output buffer") }
|
|
96
|
+
defer { BIO_free(out) }
|
|
97
|
+
|
|
98
|
+
let rc = ASN1_parse_dump(out, ptr.baseAddress?.assumingMemoryBound(to: UInt8.self), data.count, 0, 0)
|
|
99
|
+
if rc == 0 {
|
|
100
|
+
throw OpenSSLError.UnableToParseASN1("Failed to parse ASN1 Data")
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
parsed = OpenSSLUtils.bioToString(bio: out)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let lines = parsed.components(separatedBy: "\n")
|
|
107
|
+
let topItem : ASN1Item? = parseLines( lines:lines)
|
|
108
|
+
|
|
109
|
+
guard let ret = topItem else {
|
|
110
|
+
throw OpenSSLError.UnableToParseASN1("Failed to format ASN1 Data")
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return ret
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
func parseLines( lines : [String] ) -> ASN1Item? {
|
|
117
|
+
var topItem : ASN1Item?
|
|
118
|
+
|
|
119
|
+
var currentParent : ASN1Item?
|
|
120
|
+
for line in lines {
|
|
121
|
+
if line.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
|
|
122
|
+
continue
|
|
123
|
+
}
|
|
124
|
+
let item = ASN1Item(line: line)
|
|
125
|
+
if item.depth == 0 {
|
|
126
|
+
topItem = item
|
|
127
|
+
} else if item.depth == currentParent!.depth {
|
|
128
|
+
currentParent!.parent!.addChild( item )
|
|
129
|
+
} else if item.depth > currentParent!.depth {
|
|
130
|
+
currentParent!.addChild( item )
|
|
131
|
+
} else {
|
|
132
|
+
repeat {
|
|
133
|
+
currentParent = currentParent!.parent
|
|
134
|
+
} while currentParent!.depth > item.depth-1 && currentParent!.depth != 0
|
|
135
|
+
if currentParent!.depth == item.depth-1 {
|
|
136
|
+
currentParent!.addChild( item )
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
currentParent = item
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return topItem
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public func test() {
|
|
146
|
+
let lines = [
|
|
147
|
+
" 0:d=0 hl=4 l= 758 cons: SET ",
|
|
148
|
+
" 662:d=1 hl=2 l= 18 cons: SEQUENCE ",
|
|
149
|
+
" 664:d=2 hl=2 l= 10 prim: OBJECT :0.4.0.127.0.7.2.2.3.2.4",
|
|
150
|
+
" 676:d=2 hl=2 l= 1 prim: INTEGER :01",
|
|
151
|
+
" 679:d=2 hl=2 l= 1 prim: INTEGER :01",
|
|
152
|
+
" 682:d=1 hl=2 l= 18 cons: SEQUENCE ",
|
|
153
|
+
" 684:d=2 hl=2 l= 10 prim: OBJECT :0.4.0.127.0.7.2.2.3.2.1",
|
|
154
|
+
" 696:d=2 hl=2 l= 1 prim: INTEGER :01",
|
|
155
|
+
" 699:d=2 hl=2 l= 1 prim: INTEGER :02",
|
|
156
|
+
" 702:d=1 hl=2 l= 13 cons: SEQUENCE ",
|
|
157
|
+
" 704:d=2 hl=2 l= 8 prim: OBJECT :0.4.0.127.0.7.2.2.2",
|
|
158
|
+
" 714:d=2 hl=2 l= 1 prim: INTEGER :01",
|
|
159
|
+
" 717:d=1 hl=2 l= 18 cons: SEQUENCE ",
|
|
160
|
+
" 719:d=2 hl=2 l= 10 prim: OBJECT :0.4.0.127.0.7.2.2.4.2.4",
|
|
161
|
+
" 731:d=2 hl=2 l= 1 prim: INTEGER :02",
|
|
162
|
+
" 734:d=2 hl=2 l= 1 prim: INTEGER :0D",
|
|
163
|
+
" 737:d=1 hl=2 l= 23 cons: SEQUENCE ",
|
|
164
|
+
" 739:d=2 hl=2 l= 6 prim: OBJECT :2.23.136.1.1.5",
|
|
165
|
+
" 747:d=2 hl=2 l= 1 prim: INTEGER :01",
|
|
166
|
+
" 750:d=2 hl=2 l= 10 prim: OBJECT :0.4.0.127.0.7.1.1.4.1.3",
|
|
167
|
+
""
|
|
168
|
+
]
|
|
169
|
+
|
|
170
|
+
let topItem = parseLines( lines:lines )
|
|
171
|
+
print( topItem?.debugDescription ?? "" )
|
|
172
|
+
}
|
|
173
|
+
}
|