From 09684f21c726edca87500818e1374bc0f6881773 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 8 Apr 2021 21:12:43 +0200 Subject: [PATCH 01/89] Initial Commit --- PatientScannerDemo.xcodeproj/project.pbxproj | 598 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/xcschememanagement.plist | 14 + PatientScannerDemo/AppDelegate.swift | 36 ++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 98 +++ .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 + PatientScannerDemo/Base.lproj/Main.storyboard | 24 + PatientScannerDemo/Info.plist | 66 ++ PatientScannerDemo/SceneDelegate.swift | 52 ++ PatientScannerDemo/ViewController.swift | 19 + PatientScannerDemoTests/Info.plist | 22 + .../PatientScannerDemoTests.swift | 33 + PatientScannerDemoUITests/Info.plist | 22 + .../PatientScannerDemoUITests.swift | 42 ++ 17 files changed, 1083 insertions(+) create mode 100644 PatientScannerDemo.xcodeproj/project.pbxproj create mode 100644 PatientScannerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 PatientScannerDemo/AppDelegate.swift create mode 100644 PatientScannerDemo/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 PatientScannerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 PatientScannerDemo/Assets.xcassets/Contents.json create mode 100644 PatientScannerDemo/Base.lproj/LaunchScreen.storyboard create mode 100644 PatientScannerDemo/Base.lproj/Main.storyboard create mode 100644 PatientScannerDemo/Info.plist create mode 100644 PatientScannerDemo/SceneDelegate.swift create mode 100644 PatientScannerDemo/ViewController.swift create mode 100644 PatientScannerDemoTests/Info.plist create mode 100644 PatientScannerDemoTests/PatientScannerDemoTests.swift create mode 100644 PatientScannerDemoUITests/Info.plist create mode 100644 PatientScannerDemoUITests/PatientScannerDemoUITests.swift diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000..81b6a2c --- /dev/null +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -0,0 +1,598 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EB261F8D2700715333 /* AppDelegate.swift */; }; + CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */; }; + CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EF261F8D2700715333 /* ViewController.swift */; }; + CEA6D6F3261F8D2700715333 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F1261F8D2700715333 /* Main.storyboard */; }; + CEA6D6F5261F8D2900715333 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F4261F8D2900715333 /* Assets.xcassets */; }; + CEA6D6F8261F8D2900715333 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */; }; + CEA6D703261F8D2900715333 /* PatientScannerDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */; }; + CEA6D70E261F8D2900715333 /* PatientScannerDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + CEA6D6FF261F8D2900715333 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CEA6D6E0261F8D2700715333 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CEA6D6E7261F8D2700715333; + remoteInfo = PatientScannerDemo; + }; + CEA6D70A261F8D2900715333 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CEA6D6E0261F8D2700715333 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CEA6D6E7261F8D2700715333; + remoteInfo = PatientScannerDemo; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PatientScannerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + CEA6D6EB261F8D2700715333 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + CEA6D6EF261F8D2700715333 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + CEA6D6F2261F8D2700715333 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + CEA6D6F4261F8D2900715333 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + CEA6D6F7261F8D2900715333 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + CEA6D6F9261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CEA6D6FE261F8D2900715333 /* PatientScannerDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PatientScannerDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatientScannerDemoTests.swift; sourceTree = ""; }; + CEA6D704261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CEA6D709261F8D2900715333 /* PatientScannerDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PatientScannerDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatientScannerDemoUITests.swift; sourceTree = ""; }; + CEA6D70F261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + CEA6D6E5261F8D2700715333 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CEA6D6FB261F8D2900715333 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CEA6D706261F8D2900715333 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + CEA6D6DF261F8D2700715333 = { + isa = PBXGroup; + children = ( + CEA6D6EA261F8D2700715333 /* PatientScannerDemo */, + CEA6D701261F8D2900715333 /* PatientScannerDemoTests */, + CEA6D70C261F8D2900715333 /* PatientScannerDemoUITests */, + CEA6D6E9261F8D2700715333 /* Products */, + ); + sourceTree = ""; + }; + CEA6D6E9261F8D2700715333 /* Products */ = { + isa = PBXGroup; + children = ( + CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */, + CEA6D6FE261F8D2900715333 /* PatientScannerDemoTests.xctest */, + CEA6D709261F8D2900715333 /* PatientScannerDemoUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + CEA6D6EA261F8D2700715333 /* PatientScannerDemo */ = { + isa = PBXGroup; + children = ( + CEA6D6EB261F8D2700715333 /* AppDelegate.swift */, + CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */, + CEA6D6EF261F8D2700715333 /* ViewController.swift */, + CEA6D6F1261F8D2700715333 /* Main.storyboard */, + CEA6D6F4261F8D2900715333 /* Assets.xcassets */, + CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */, + CEA6D6F9261F8D2900715333 /* Info.plist */, + ); + path = PatientScannerDemo; + sourceTree = ""; + }; + CEA6D701261F8D2900715333 /* PatientScannerDemoTests */ = { + isa = PBXGroup; + children = ( + CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */, + CEA6D704261F8D2900715333 /* Info.plist */, + ); + path = PatientScannerDemoTests; + sourceTree = ""; + }; + CEA6D70C261F8D2900715333 /* PatientScannerDemoUITests */ = { + isa = PBXGroup; + children = ( + CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */, + CEA6D70F261F8D2900715333 /* Info.plist */, + ); + path = PatientScannerDemoUITests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + CEA6D6E7261F8D2700715333 /* PatientScannerDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = CEA6D712261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemo" */; + buildPhases = ( + CEA6D6E4261F8D2700715333 /* Sources */, + CEA6D6E5261F8D2700715333 /* Frameworks */, + CEA6D6E6261F8D2700715333 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PatientScannerDemo; + productName = PatientScannerDemo; + productReference = CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */; + productType = "com.apple.product-type.application"; + }; + CEA6D6FD261F8D2900715333 /* PatientScannerDemoTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = CEA6D715261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemoTests" */; + buildPhases = ( + CEA6D6FA261F8D2900715333 /* Sources */, + CEA6D6FB261F8D2900715333 /* Frameworks */, + CEA6D6FC261F8D2900715333 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + CEA6D700261F8D2900715333 /* PBXTargetDependency */, + ); + name = PatientScannerDemoTests; + productName = PatientScannerDemoTests; + productReference = CEA6D6FE261F8D2900715333 /* PatientScannerDemoTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + CEA6D708261F8D2900715333 /* PatientScannerDemoUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = CEA6D718261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemoUITests" */; + buildPhases = ( + CEA6D705261F8D2900715333 /* Sources */, + CEA6D706261F8D2900715333 /* Frameworks */, + CEA6D707261F8D2900715333 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + CEA6D70B261F8D2900715333 /* PBXTargetDependency */, + ); + name = PatientScannerDemoUITests; + productName = PatientScannerDemoUITests; + productReference = CEA6D709261F8D2900715333 /* PatientScannerDemoUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + CEA6D6E0261F8D2700715333 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1240; + LastUpgradeCheck = 1240; + TargetAttributes = { + CEA6D6E7261F8D2700715333 = { + CreatedOnToolsVersion = 12.4; + }; + CEA6D6FD261F8D2900715333 = { + CreatedOnToolsVersion = 12.4; + TestTargetID = CEA6D6E7261F8D2700715333; + }; + CEA6D708261F8D2900715333 = { + CreatedOnToolsVersion = 12.4; + TestTargetID = CEA6D6E7261F8D2700715333; + }; + }; + }; + buildConfigurationList = CEA6D6E3261F8D2700715333 /* Build configuration list for PBXProject "PatientScannerDemo" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = CEA6D6DF261F8D2700715333; + productRefGroup = CEA6D6E9261F8D2700715333 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + CEA6D6E7261F8D2700715333 /* PatientScannerDemo */, + CEA6D6FD261F8D2900715333 /* PatientScannerDemoTests */, + CEA6D708261F8D2900715333 /* PatientScannerDemoUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + CEA6D6E6261F8D2700715333 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CEA6D6F8261F8D2900715333 /* LaunchScreen.storyboard in Resources */, + CEA6D6F5261F8D2900715333 /* Assets.xcassets in Resources */, + CEA6D6F3261F8D2700715333 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CEA6D6FC261F8D2900715333 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CEA6D707261F8D2900715333 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + CEA6D6E4261F8D2700715333 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, + CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, + CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CEA6D6FA261F8D2900715333 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CEA6D703261F8D2900715333 /* PatientScannerDemoTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CEA6D705261F8D2900715333 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CEA6D70E261F8D2900715333 /* PatientScannerDemoUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + CEA6D700261F8D2900715333 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = CEA6D6E7261F8D2700715333 /* PatientScannerDemo */; + targetProxy = CEA6D6FF261F8D2900715333 /* PBXContainerItemProxy */; + }; + CEA6D70B261F8D2900715333 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = CEA6D6E7261F8D2700715333 /* PatientScannerDemo */; + targetProxy = CEA6D70A261F8D2900715333 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + CEA6D6F1261F8D2700715333 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + CEA6D6F2261F8D2700715333 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + CEA6D6F7261F8D2900715333 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + CEA6D710261F8D2900715333 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.4; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + CEA6D711261F8D2900715333 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + CEA6D713261F8D2900715333 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = KH99XNF745; + INFOPLIST_FILE = PatientScannerDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemo"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + CEA6D714261F8D2900715333 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = KH99XNF745; + INFOPLIST_FILE = PatientScannerDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemo"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + CEA6D716261F8D2900715333 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = KH99XNF745; + INFOPLIST_FILE = PatientScannerDemoTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemoTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PatientScannerDemo.app/PatientScannerDemo"; + }; + name = Debug; + }; + CEA6D717261F8D2900715333 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = KH99XNF745; + INFOPLIST_FILE = PatientScannerDemoTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemoTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PatientScannerDemo.app/PatientScannerDemo"; + }; + name = Release; + }; + CEA6D719261F8D2900715333 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = KH99XNF745; + INFOPLIST_FILE = PatientScannerDemoUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemoUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = PatientScannerDemo; + }; + name = Debug; + }; + CEA6D71A261F8D2900715333 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = KH99XNF745; + INFOPLIST_FILE = PatientScannerDemoUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemoUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = PatientScannerDemo; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + CEA6D6E3261F8D2700715333 /* Build configuration list for PBXProject "PatientScannerDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CEA6D710261F8D2900715333 /* Debug */, + CEA6D711261F8D2900715333 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CEA6D712261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CEA6D713261F8D2900715333 /* Debug */, + CEA6D714261F8D2900715333 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CEA6D715261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemoTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CEA6D716261F8D2900715333 /* Debug */, + CEA6D717261F8D2900715333 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CEA6D718261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemoUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CEA6D719261F8D2900715333 /* Debug */, + CEA6D71A261F8D2900715333 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = CEA6D6E0261F8D2700715333 /* Project object */; +} diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/PatientScannerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/PatientScannerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist b/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..3949b55 --- /dev/null +++ b/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + PatientScannerDemo.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/PatientScannerDemo/AppDelegate.swift b/PatientScannerDemo/AppDelegate.swift new file mode 100644 index 0000000..8294195 --- /dev/null +++ b/PatientScannerDemo/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/8/21. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/PatientScannerDemo/Assets.xcassets/AccentColor.colorset/Contents.json b/PatientScannerDemo/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/PatientScannerDemo/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PatientScannerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/PatientScannerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/PatientScannerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PatientScannerDemo/Assets.xcassets/Contents.json b/PatientScannerDemo/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/PatientScannerDemo/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PatientScannerDemo/Base.lproj/LaunchScreen.storyboard b/PatientScannerDemo/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/PatientScannerDemo/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PatientScannerDemo/Base.lproj/Main.storyboard b/PatientScannerDemo/Base.lproj/Main.storyboard new file mode 100644 index 0000000..25a7638 --- /dev/null +++ b/PatientScannerDemo/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PatientScannerDemo/Info.plist b/PatientScannerDemo/Info.plist new file mode 100644 index 0000000..5b531f7 --- /dev/null +++ b/PatientScannerDemo/Info.plist @@ -0,0 +1,66 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/PatientScannerDemo/SceneDelegate.swift b/PatientScannerDemo/SceneDelegate.swift new file mode 100644 index 0000000..22880e4 --- /dev/null +++ b/PatientScannerDemo/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/8/21. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/PatientScannerDemo/ViewController.swift b/PatientScannerDemo/ViewController.swift new file mode 100644 index 0000000..5ff7552 --- /dev/null +++ b/PatientScannerDemo/ViewController.swift @@ -0,0 +1,19 @@ +// +// ViewController.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/8/21. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + +} + diff --git a/PatientScannerDemoTests/Info.plist b/PatientScannerDemoTests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/PatientScannerDemoTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/PatientScannerDemoTests/PatientScannerDemoTests.swift b/PatientScannerDemoTests/PatientScannerDemoTests.swift new file mode 100644 index 0000000..11b58a1 --- /dev/null +++ b/PatientScannerDemoTests/PatientScannerDemoTests.swift @@ -0,0 +1,33 @@ +// +// PatientScannerDemoTests.swift +// PatientScannerDemoTests +// +// Created by Yannick Spreen on 4/8/21. +// + +import XCTest +@testable import PatientScannerDemo + +class PatientScannerDemoTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/PatientScannerDemoUITests/Info.plist b/PatientScannerDemoUITests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/PatientScannerDemoUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/PatientScannerDemoUITests/PatientScannerDemoUITests.swift b/PatientScannerDemoUITests/PatientScannerDemoUITests.swift new file mode 100644 index 0000000..2dadbd5 --- /dev/null +++ b/PatientScannerDemoUITests/PatientScannerDemoUITests.swift @@ -0,0 +1,42 @@ +// +// PatientScannerDemoUITests.swift +// PatientScannerDemoUITests +// +// Created by Yannick Spreen on 4/8/21. +// + +import XCTest + +class PatientScannerDemoUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() throws { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } + } +} From 69fdcf7ae7143191f2724c79e20be8a0d0526af8 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Mon, 12 Apr 2021 22:56:44 +0200 Subject: [PATCH 02/89] Scan code via iOS APIs, decode b45 and CBOR. Not compiling without errors: Currently experimenting with the Kitura Cryptor library which has some issues on iOS. --- .gitignore | 220 ++++++++++++++++++ PatientScannerDemo.xcodeproj/project.pbxproj | 75 +++++- .../xcshareddata/swiftpm/Package.resolved | 43 ++++ PatientScannerDemo/AppDelegate.swift | 17 -- PatientScannerDemo/Base45.swift | 73 ++++++ PatientScannerDemo/Info.plist | 2 + PatientScannerDemo/SceneDelegate.swift | 37 --- PatientScannerDemo/ViewController.swift | 217 ++++++++++++++++- PatientScannerDemo/ZLib.swift | 28 +++ 9 files changed, 654 insertions(+), 58 deletions(-) create mode 100644 .gitignore create mode 100644 PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 PatientScannerDemo/Base45.swift create mode 100644 PatientScannerDemo/ZLib.swift diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83296ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,220 @@ +######################### +# .gitignore file for Xcode4 and Xcode5 Source projects +# +# Apple bugs, waiting for Apple to fix/respond: +# +# 15564624 - what does the xccheckout file in Xcode5 do? Where's the documentation? +# +# Version 2.6 +# For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects +# +# 2015 updates: +# - Fixed typo in "xccheckout" line - thanks to @lyck for pointing it out! +# - Fixed the .idea optional ignore. Thanks to @hashier for pointing this out +# - Finally added "xccheckout" to the ignore. Apple still refuses to answer support requests about this, but in practice it seems you should ignore it. +# - minor tweaks from Jona and Coeur (slightly more precise xc* filtering/names) +# 2014 updates: +# - appended non-standard items DISABLED by default (uncomment if you use those tools) +# - removed the edit that an SO.com moderator made without bothering to ask me +# - researched CocoaPods .lock more carefully, thanks to Gokhan Celiker +# 2013 updates: +# - fixed the broken "save personal Schemes" +# - added line-by-line explanations for EVERYTHING (some were missing) +# +# NB: if you are storing "built" products, this WILL NOT WORK, +# and you should use a different .gitignore (or none at all) +# This file is for SOURCE projects, where there are many extra +# files that we want to exclude +# +######################### + +##### +# OS X temporary files that should never be committed +# +# c.f. http://www.westwind.com/reference/os-x/invisibles.html + +.DS_Store + +# c.f. http://www.westwind.com/reference/os-x/invisibles.html + +.Trashes + +# c.f. http://www.westwind.com/reference/os-x/invisibles.html + +*.swp + +# +# *.lock - this is used and abused by many editors for many different things. +# For the main ones I use (e.g. Eclipse), it should be excluded +# from source-control, but YMMV. +# (lock files are usually local-only file-synchronization on the local FS that should NOT go in git) +# c.f. the "OPTIONAL" section at bottom though, for tool-specific variations! +# +# In particular, if you're using CocoaPods, you'll want to comment-out this line: +# *.lock + + +# +# profile - REMOVED temporarily (on double-checking, I can't find it in OS X docs?) +#profile + + +#### +# Xcode temporary files that should never be committed +# +# NB: NIB/XIB files still exist even on Storyboard projects, so we want this... + +*~.nib + + +#### +# Xcode build files - +# +# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" + +DerivedData/ + +# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" + +build/ + + +##### +# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) +# +# This is complicated: +# +# SOMETIMES you need to put this file in version control. +# Apple designed it poorly - if you use "custom executables", they are +# saved in this file. +# 99% of projects do NOT use those, so they do NOT want to version control this file. +# ..but if you're in the 1%, comment out the line "*.pbxuser" + +# .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html + +*.pbxuser + +# .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html + +*.mode1v3 + +# .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html + +*.mode2v3 + +# .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file + +*.perspectivev3 + +# NB: also, whitelist the default ones, some projects need to use these +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + + +#### +# Xcode 4 - semi-personal settings +# +# Apple Shared data that Apple put in the wrong folder +# c.f. http://stackoverflow.com/a/19260712/153422 +# FROM ANSWER: Apple says "don't ignore it" +# FROM COMMENTS: Apple is wrong; Apple code is too buggy to trust; there are no known negative side-effects to ignoring Apple's unofficial advice and instead doing the thing that actively fixes bugs in Xcode +# Up to you, but ... current advice: ignore it. +*.xccheckout + +# +# +# OPTION 1: --------------------------------- +# throw away ALL personal settings (including custom schemes! +# - unless they are "shared") +# As per build/ and DerivedData/, this ought to have a trailing slash +# +# NB: this is exclusive with OPTION 2 below +xcuserdata/ + +# OPTION 2: --------------------------------- +# get rid of ALL personal settings, but KEEP SOME OF THEM +# - NB: you must manually uncomment the bits you want to keep +# +# NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X, +# or manually install git over the top of the OS X version +# NB: this is exclusive with OPTION 1 above +# +#xcuserdata/**/* + +# (requires option 2 above): Personal Schemes +# +#!xcuserdata/**/xcschemes/* + +#### +# XCode 4 workspaces - more detailed +# +# Workspaces are important! They are a core feature of Xcode - don't exclude them :) +# +# Workspace layout is quite spammy. For reference: +# +# /(root)/ +# /(project-name).xcodeproj/ +# project.pbxproj +# /project.xcworkspace/ +# contents.xcworkspacedata +# /xcuserdata/ +# /(your name)/xcuserdatad/ +# UserInterfaceState.xcuserstate +# /xcshareddata/ +# /xcschemes/ +# (shared scheme name).xcscheme +# /xcuserdata/ +# /(your name)/xcuserdatad/ +# (private scheme).xcscheme +# xcschememanagement.plist +# +# + +#### +# Xcode 4 - Deprecated classes +# +# Allegedly, if you manually "deprecate" your classes, they get moved here. +# +# We're using source-control, so this is a "feature" that we do not want! + +*.moved-aside + +#### +# OPTIONAL: Some well-known tools that people use side-by-side with Xcode / iOS development +# +# NB: I'd rather not include these here, but gitignore's design is weak and doesn't allow +# modular gitignore: you have to put EVERYTHING in one file. +# +# COCOAPODS: +# +# c.f. http://guides.cocoapods.org/using/using-cocoapods.html#what-is-a-podfilelock +# c.f. http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control +# +#!Podfile.lock +# +# RUBY: +# +# c.f. http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ +# +#!Gemfile.lock +# +# IDEA: +# +# c.f. https://www.jetbrains.com/objc/help/managing-projects-under-version-control.html?search=workspace.xml +# +#.idea/workspace.xml +# +# TEXTMATE: +# +# -- UNVERIFIED: c.f. http://stackoverflow.com/a/50283/153422 +# +#tm_build_errors + +#### +# UNKNOWN: recommended by others, but I can't discover what these files are +# + + +/Pods/ \ No newline at end of file diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 81b6a2c..4d61507 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -3,10 +3,12 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ + CE5D7A392620D6CA001DFEEF /* SwiftJWKtoPEM in Frameworks */ = {isa = PBXBuildFile; productRef = CE5D7A382620D6CA001DFEEF /* SwiftJWKtoPEM */; }; + CE5D7A422620DA45001DFEEF /* CryptorECC in Frameworks */ = {isa = PBXBuildFile; productRef = CE5D7A412620DA45001DFEEF /* CryptorECC */; }; CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EB261F8D2700715333 /* AppDelegate.swift */; }; CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */; }; CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EF261F8D2700715333 /* ViewController.swift */; }; @@ -15,6 +17,9 @@ CEA6D6F8261F8D2900715333 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */; }; CEA6D703261F8D2900715333 /* PatientScannerDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */; }; CEA6D70E261F8D2900715333 /* PatientScannerDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */; }; + CEB78C4A261F8DA200FB8F68 /* Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB78C48261F8DA200FB8F68 /* Base45.swift */; }; + CEB78C4B261F8DA200FB8F68 /* ZLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB78C49261F8DA200FB8F68 /* ZLib.swift */; }; + CEB78C57261F8DE100FB8F68 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CEB78C56261F8DE100FB8F68 /* SwiftCBOR */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -49,6 +54,8 @@ CEA6D709261F8D2900715333 /* PatientScannerDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PatientScannerDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatientScannerDemoUITests.swift; sourceTree = ""; }; CEA6D70F261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CEB78C48261F8DA200FB8F68 /* Base45.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Base45.swift; sourceTree = ""; }; + CEB78C49261F8DA200FB8F68 /* ZLib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZLib.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -56,6 +63,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + CE5D7A422620DA45001DFEEF /* CryptorECC in Frameworks */, + CEB78C57261F8DE100FB8F68 /* SwiftCBOR in Frameworks */, + CE5D7A392620D6CA001DFEEF /* SwiftJWKtoPEM in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -99,6 +109,8 @@ CEA6D6EA261F8D2700715333 /* PatientScannerDemo */ = { isa = PBXGroup; children = ( + CEB78C48261F8DA200FB8F68 /* Base45.swift */, + CEB78C49261F8DA200FB8F68 /* ZLib.swift */, CEA6D6EB261F8D2700715333 /* AppDelegate.swift */, CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */, CEA6D6EF261F8D2700715333 /* ViewController.swift */, @@ -144,6 +156,11 @@ dependencies = ( ); name = PatientScannerDemo; + packageProductDependencies = ( + CEB78C56261F8DE100FB8F68 /* SwiftCBOR */, + CE5D7A382620D6CA001DFEEF /* SwiftJWKtoPEM */, + CE5D7A412620DA45001DFEEF /* CryptorECC */, + ); productName = PatientScannerDemo; productReference = CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */; productType = "com.apple.product-type.application"; @@ -215,6 +232,11 @@ Base, ); mainGroup = CEA6D6DF261F8D2700715333; + packageReferences = ( + CEB78C55261F8DE100FB8F68 /* XCRemoteSwiftPackageReference "SwiftCBOR" */, + CE5D7A372620D6CA001DFEEF /* XCRemoteSwiftPackageReference "Swift-JWK-to-PEM" */, + CE5D7A402620DA45001DFEEF /* XCRemoteSwiftPackageReference "BlueECC" */, + ); productRefGroup = CEA6D6E9261F8D2700715333 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -258,9 +280,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CEB78C4B261F8DA200FB8F68 /* ZLib.swift in Sources */, CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */, + CEB78C4A261F8DA200FB8F68 /* Base45.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -366,7 +390,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.4; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -421,7 +445,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.4; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; @@ -593,6 +617,51 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + CE5D7A372620D6CA001DFEEF /* XCRemoteSwiftPackageReference "Swift-JWK-to-PEM" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/ibm-cloud-security/Swift-JWK-to-PEM"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.4.0; + }; + }; + CE5D7A402620DA45001DFEEF /* XCRemoteSwiftPackageReference "BlueECC" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Kitura/BlueECC"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.2.5; + }; + }; + CEB78C55261F8DE100FB8F68 /* XCRemoteSwiftPackageReference "SwiftCBOR" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/unrelentingtech/SwiftCBOR"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.4.3; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + CE5D7A382620D6CA001DFEEF /* SwiftJWKtoPEM */ = { + isa = XCSwiftPackageProductDependency; + package = CE5D7A372620D6CA001DFEEF /* XCRemoteSwiftPackageReference "Swift-JWK-to-PEM" */; + productName = SwiftJWKtoPEM; + }; + CE5D7A412620DA45001DFEEF /* CryptorECC */ = { + isa = XCSwiftPackageProductDependency; + package = CE5D7A402620DA45001DFEEF /* XCRemoteSwiftPackageReference "BlueECC" */; + productName = CryptorECC; + }; + CEB78C56261F8DE100FB8F68 /* SwiftCBOR */ = { + isa = XCSwiftPackageProductDependency; + package = CEB78C55261F8DE100FB8F68 /* XCRemoteSwiftPackageReference "SwiftCBOR" */; + productName = SwiftCBOR; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = CEA6D6E0261F8D2700715333 /* Project object */; } diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..91582d9 --- /dev/null +++ b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,43 @@ +{ + "object": { + "pins": [ + { + "package": "CryptorECC", + "repositoryURL": "https://github.com/Kitura/BlueECC", + "state": { + "branch": null, + "revision": "baf6ed3fc1a622675f0041b4aff7c02dd1a93818", + "version": "1.2.200" + } + }, + { + "package": "OpenSSL", + "repositoryURL": "https://github.com/IBM-Swift/OpenSSL.git", + "state": { + "branch": null, + "revision": "80b04f33b086fc90e28d9ae159d43705fb348e16", + "version": "2.2.200" + } + }, + { + "package": "SwiftJWKtoPEM", + "repositoryURL": "https://github.com/ibm-cloud-security/Swift-JWK-to-PEM", + "state": { + "branch": null, + "revision": "b18e2af1392bb84f1cde83b1e00847051c9fdda6", + "version": "0.4.0" + } + }, + { + "package": "SwiftCBOR", + "repositoryURL": "https://github.com/unrelentingtech/SwiftCBOR", + "state": { + "branch": null, + "revision": "668c26fc3373d5f1bccbaad7665ca6048797e324", + "version": "0.4.3" + } + } + ] + }, + "version": 1 +} diff --git a/PatientScannerDemo/AppDelegate.swift b/PatientScannerDemo/AppDelegate.swift index 8294195..9e403d6 100644 --- a/PatientScannerDemo/AppDelegate.swift +++ b/PatientScannerDemo/AppDelegate.swift @@ -10,27 +10,10 @@ import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } - // MARK: UISceneSession Lifecycle - - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) - } - - func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. - } - - } diff --git a/PatientScannerDemo/Base45.swift b/PatientScannerDemo/Base45.swift new file mode 100644 index 0000000..a4453ef --- /dev/null +++ b/PatientScannerDemo/Base45.swift @@ -0,0 +1,73 @@ +// +// Base45.swift +// Base45-Swift +// +// Created by Dirk-Willem van Gulik on 01/04/2021. +// +import Foundation + +extension String { + enum Base45Error: Error { + case Base64InvalidCharacter + case Base64InvalidLength + } + + public func fromBase45() throws ->Data { + let BASE45_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" + var d = Data() + var o = Data() + + for c in self.uppercased() { + if let at = BASE45_CHARSET.firstIndex(of: c) { + let idx = BASE45_CHARSET.distance(from: BASE45_CHARSET.startIndex, to: at) + d.append(UInt8(idx)) + } else { + throw Base45Error.Base64InvalidCharacter + } + } + for i in stride(from:0, to:d.count, by: 3) { + if (d.count - i < 2) { + throw Base45Error.Base64InvalidLength + } + var x : UInt32 = UInt32(d[i]) + UInt32(d[i+1])*45 + if (d.count - i >= 3) { + x += 45 * 45 * UInt32(d[i+2]) + o.append(UInt8(x / 256)) + } + o.append(UInt8(x % 256)) + } + return o + } +} + +extension String { + subscript(i: Int) -> String { + return String(self[index(startIndex, offsetBy: i)]) + } +} + +extension Data { + public func toBase45()->String { + let BASE45_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" + var o = String() + for i in stride(from:0, to:self.count, by: 2) { + if (self.count - i > 1) { + let x : Int = (Int(self[i])<<8) + Int(self[i+1]) + let e : Int = x / (45*45) + let x2 : Int = x % (45*45) + let d : Int = x2 / 45 + let c : Int = x2 % 45 + o.append(BASE45_CHARSET[c]) + o.append(BASE45_CHARSET[d]) + o.append(BASE45_CHARSET[e]) + } else { + let x2 : Int = Int(self[i]) + let d : Int = x2 / 45 + let c : Int = x2 % 45 + o.append(BASE45_CHARSET[c]) + o.append(BASE45_CHARSET[d]) + } + } + return o + } +} diff --git a/PatientScannerDemo/Info.plist b/PatientScannerDemo/Info.plist index 5b531f7..8c2a309 100644 --- a/PatientScannerDemo/Info.plist +++ b/PatientScannerDemo/Info.plist @@ -2,6 +2,8 @@ + NSCameraUsageDescription + Scan barcodes with your camera. CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable diff --git a/PatientScannerDemo/SceneDelegate.swift b/PatientScannerDemo/SceneDelegate.swift index 22880e4..ef39680 100644 --- a/PatientScannerDemo/SceneDelegate.swift +++ b/PatientScannerDemo/SceneDelegate.swift @@ -11,42 +11,5 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? - - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). - guard let _ = (scene as? UIWindowScene) else { return } - } - - func sceneDidDisconnect(_ scene: UIScene) { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). - } - - func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } - - func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). - } - - func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. - } - - func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. - } - - } diff --git a/PatientScannerDemo/ViewController.swift b/PatientScannerDemo/ViewController.swift index 5ff7552..5d46fe1 100644 --- a/PatientScannerDemo/ViewController.swift +++ b/PatientScannerDemo/ViewController.swift @@ -4,16 +4,231 @@ // // Created by Yannick Spreen on 4/8/21. // +// https://www.raywenderlich.com/12663654-vision-framework-tutorial-for-ios-scanning-barcodes +// import UIKit +import Vision +import AVFoundation +import SwiftCBOR +import SwiftJWKtoPEM +//import CryptorECC + class ViewController: UIViewController { + var captureSession = AVCaptureSession() + + lazy var detectBarcodeRequest = VNDetectBarcodesRequest { request, error in + guard error == nil else { + self.showAlert(withTitle: "Barcode error", message: error?.localizedDescription ?? "error") + return + } + self.processClassification(request) + } override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view. + checkPermissions() + setupCameraLiveView() + observationHandler(payloadS: nil) + } + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + captureSession.stopRunning() + } +// let curve: EllipticCurve = .prime256v1 + let name: String = "ECDSA" + + // Send the base64URLencoded signature and `header.claims` to BlueECC for verification. +// func verifySignature(key: Data, signature: Data, for data: Data) -> Bool { +// do { +// guard let keyString = String(data: key, encoding: .utf8) else { +// return false +// } +// let r = signature.subdata(in: 0 ..< signature.count/2) +// let s = signature.subdata(in: signature.count/2 ..< signature.count) +// let signature = try ECSignature(r: r, s: s) +// let publicKey = try ECPublicKey(key: keyString) +// guard publicKey.curve == curve else { +// return false +// } +// return signature.verify(plaintext: data, using: publicKey) +// } +// catch { +// print("Verification failed: \(error)") +// return false +// } +// +// } +} + + +extension ViewController { + private func checkPermissions() { + switch AVCaptureDevice.authorizationStatus(for: .video) { + case .notDetermined: + AVCaptureDevice.requestAccess(for: .video) { [self] granted in + if !granted { + self.showPermissionsAlert() + } + } + case .denied, .restricted: + showPermissionsAlert() + default: + return + } + } + + private func setupCameraLiveView() { + captureSession.sessionPreset = .hd1280x720 + + let videoDevice = AVCaptureDevice + .default(.builtInWideAngleCamera, for: .video, position: .back) + + guard + let device = videoDevice, + let videoDeviceInput = try? AVCaptureDeviceInput(device: device), + captureSession.canAddInput(videoDeviceInput) else { + showAlert( + withTitle: "Cannot Find Camera", + message: "There seems to be a problem with the camera on your device.") + return + } + + captureSession.addInput(videoDeviceInput) + + let captureOutput = AVCaptureVideoDataOutput() + captureOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)] + captureOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default)) + captureSession.addOutput(captureOutput) + + configurePreviewLayer() + + captureSession.startRunning() + } + + func processClassification(_ request: VNRequest) { + guard let barcodes = request.results else { return } + DispatchQueue.main.async { [self] in + if captureSession.isRunning { + view.layer.sublayers?.removeSubrange(1...) + + for barcode in barcodes { + let _ = barcode + guard + let potentialQRCode = barcode as? VNBarcodeObservation, + [.Aztec, .QR, .DataMatrix].contains(potentialQRCode.symbology), + potentialQRCode.confidence > 0.9 + else { return } + + print(potentialQRCode.symbology) + observationHandler(payloadS: potentialQRCode.payloadStringValue) + } + } + } } + func observationHandler(payloadS: String?) { + let payloadS: String? = "HC1NCFOXNEG2NBJ5*H:QO-.O /MD064 PJ26UV0 XHLQ9HXKZNEQCSJ591MVBATW$4 S8$96NF6OR5UVBJUB4PJU47326/Z7PCL394Z/MWP4 N66ED6JC:JEG.CZJC0:C6JK:JM$JLAINN6BLHM035L8CCECS.CYMCPOJ5OI9YI:8DRFC%PD*ZLJ9CWVBREJFZM4A7Z/M*+Q.28+VQXCRAHAF27I9QQ60E2KYIJPOJI7J/VJ0 JYSJEZIK7B*IJS7BCLIOCISEBTKBRHSWKJ4:2POJ.GILYJ7GPSVBY4CJZIOMI$MI1VC3TCYR6HCRF46Q96W/6-DP+%PPMC1KJG%HJ*81.7 84-W6I RO5PH6UDUH+/F9PJCQFRVV 8UDJ5QEV2Y8%635OHH0E2:E5VUJZ4 VT3+6ZU598O:E0/ 0VP2IBO6ANG%6UD5RSRO4B6$ES40H/CQ1" + guard + let payloadString = payloadS, + let compressed = try? String(payloadString.dropFirst(3)).fromBase45() + else { return } + + let data = decompress(compressed) + var s = "" + for char in data { + s += String(data: Data([char]), encoding: .utf8) ?? "?" + } + + print(data) + let decoder = SwiftCBOR.CBORDecoder(input: [UInt8](data)) + guard + let cose = try? decoder.decodeItem(), + case let CBOR.tagged(tag, cborElement) = cose, + tag.rawValue == 18, + case let CBOR.array(array) = cborElement, + case let CBOR.byteString(protectedBytes) = array[0], + case let CBOR.map(unprotected) = array[1], + case let CBOR.byteString(payloadBytes) = array[2], + case let CBOR.byteString(signature) = array[3], + let protected = try? CBOR.decode(protectedBytes), + let payload = try? CBOR.decode(payloadBytes) + else { + return + } + + print("START") + print(protected) + print(unprotected) + print(payload) + print(signature) + print("END") + print() + print() + // print(s) + + let keyString = """ +{ + "crv": "P-256", + "kid": "MklRdnVDMEdIZ29EeVY5VHo2WDR5MGlHTFNCZTgxdE5iN2wzYTZsUElCUQ", + "kty": "EC", + "x": "DHJudz6lqcTXizpz4cb_bbi8NZ9ofoD3lYnvByrMfLc", + "y": "bP7L_fysDzwFc13DDEPllO2qu1nDiDd1btoVQ-XlKok" +} +""" + + let key = try! RSAKey(jwk: keyString) + + let publicPem = try! key.getPublicKey() + +// let verifier = verifySignature(key: publicPem!.data(using: .utf8)!, signature: Data(signature), for: Data(payloadBytes)) +// print(verifier) + + } } + +extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate { + func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { + guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return } + + let imageRequestHandler = VNImageRequestHandler( + cvPixelBuffer: pixelBuffer, + orientation: .right + ) + + do { + try imageRequestHandler.perform([detectBarcodeRequest]) + } catch { + print(error) + } + } +} + + +extension ViewController { + private func configurePreviewLayer() { + let cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) + cameraPreviewLayer.videoGravity = .resizeAspectFill + cameraPreviewLayer.connection?.videoOrientation = .portrait + cameraPreviewLayer.frame = view.frame + view.layer.insertSublayer(cameraPreviewLayer, at: 0) + } + + private func showAlert(withTitle title: String, message: String) { + DispatchQueue.main.async { + let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: "OK", style: .default)) + self.present(alertController, animated: true) + } + } + + private func showPermissionsAlert() { + showAlert( + withTitle: "Camera Permissions", + message: "Please open Settings and grant permission for this app to use your camera." + ) + } +} diff --git a/PatientScannerDemo/ZLib.swift b/PatientScannerDemo/ZLib.swift new file mode 100644 index 0000000..8c40f53 --- /dev/null +++ b/PatientScannerDemo/ZLib.swift @@ -0,0 +1,28 @@ +// https://stackoverflow.com/a/55558641/2585092 + +import Foundation +import Compression + +func decompressString(_ data: Data) -> String { + let size = 4 * data.count + let buffer = UnsafeMutablePointer.allocate(capacity: size) + let result = data.subdata(in: 2 ..< data.count).withUnsafeBytes ({ + let read = compression_decode_buffer(buffer, size, $0.baseAddress!.bindMemory(to: UInt8.self, capacity: 1), + data.count - 2, nil, COMPRESSION_ZLIB) + return String(decoding: Data(bytes: buffer, count:read), as: UTF8.self) + }) as String + buffer.deallocate() + return result +} + +func decompress(_ data: Data) -> Data { + let size = 4 * data.count + let buffer = UnsafeMutablePointer.allocate(capacity: size) + let result = data.subdata(in: 2 ..< data.count).withUnsafeBytes ({ + let read = compression_decode_buffer(buffer, size, $0.baseAddress!.bindMemory(to: UInt8.self, capacity: 1), + data.count - 2, nil, COMPRESSION_ZLIB) + return Data(bytes: buffer, count:read) + }) as Data + buffer.deallocate() + return result +} From 5513f4564c7ad3911ce0a4b9a50f978d3bd4c045 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Tue, 13 Apr 2021 16:09:22 +0200 Subject: [PATCH 03/89] Add JWK to SecKey function; Remove some crypt packages. --- PatientScannerDemo.xcodeproj/project.pbxproj | 38 +------- .../xcdebugger/Breakpoints_v2.xcbkptlist | 88 +++++++++++++++++++ PatientScannerDemo/JWK.swift | 48 ++++++++++ PatientScannerDemo/ViewController.swift | 7 +- 4 files changed, 143 insertions(+), 38 deletions(-) create mode 100644 PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 PatientScannerDemo/JWK.swift diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 4d61507..3849fee 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -7,8 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - CE5D7A392620D6CA001DFEEF /* SwiftJWKtoPEM in Frameworks */ = {isa = PBXBuildFile; productRef = CE5D7A382620D6CA001DFEEF /* SwiftJWKtoPEM */; }; - CE5D7A422620DA45001DFEEF /* CryptorECC in Frameworks */ = {isa = PBXBuildFile; productRef = CE5D7A412620DA45001DFEEF /* CryptorECC */; }; CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EB261F8D2700715333 /* AppDelegate.swift */; }; CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */; }; CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EF261F8D2700715333 /* ViewController.swift */; }; @@ -20,6 +18,7 @@ CEB78C4A261F8DA200FB8F68 /* Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB78C48261F8DA200FB8F68 /* Base45.swift */; }; CEB78C4B261F8DA200FB8F68 /* ZLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB78C49261F8DA200FB8F68 /* ZLib.swift */; }; CEB78C57261F8DE100FB8F68 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CEB78C56261F8DE100FB8F68 /* SwiftCBOR */; }; + CED0DCFE2625DC0100CBB5CE /* JWK.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED0DCFD2625DC0100CBB5CE /* JWK.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -56,6 +55,7 @@ CEA6D70F261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; CEB78C48261F8DA200FB8F68 /* Base45.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Base45.swift; sourceTree = ""; }; CEB78C49261F8DA200FB8F68 /* ZLib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZLib.swift; sourceTree = ""; }; + CED0DCFD2625DC0100CBB5CE /* JWK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWK.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -63,9 +63,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - CE5D7A422620DA45001DFEEF /* CryptorECC in Frameworks */, CEB78C57261F8DE100FB8F68 /* SwiftCBOR in Frameworks */, - CE5D7A392620D6CA001DFEEF /* SwiftJWKtoPEM in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -118,6 +116,7 @@ CEA6D6F4261F8D2900715333 /* Assets.xcassets */, CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */, CEA6D6F9261F8D2900715333 /* Info.plist */, + CED0DCFD2625DC0100CBB5CE /* JWK.swift */, ); path = PatientScannerDemo; sourceTree = ""; @@ -158,8 +157,6 @@ name = PatientScannerDemo; packageProductDependencies = ( CEB78C56261F8DE100FB8F68 /* SwiftCBOR */, - CE5D7A382620D6CA001DFEEF /* SwiftJWKtoPEM */, - CE5D7A412620DA45001DFEEF /* CryptorECC */, ); productName = PatientScannerDemo; productReference = CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */; @@ -234,8 +231,6 @@ mainGroup = CEA6D6DF261F8D2700715333; packageReferences = ( CEB78C55261F8DE100FB8F68 /* XCRemoteSwiftPackageReference "SwiftCBOR" */, - CE5D7A372620D6CA001DFEEF /* XCRemoteSwiftPackageReference "Swift-JWK-to-PEM" */, - CE5D7A402620DA45001DFEEF /* XCRemoteSwiftPackageReference "BlueECC" */, ); productRefGroup = CEA6D6E9261F8D2700715333 /* Products */; projectDirPath = ""; @@ -282,6 +277,7 @@ files = ( CEB78C4B261F8DA200FB8F68 /* ZLib.swift in Sources */, CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, + CED0DCFE2625DC0100CBB5CE /* JWK.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */, CEB78C4A261F8DA200FB8F68 /* Base45.swift in Sources */, @@ -619,22 +615,6 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - CE5D7A372620D6CA001DFEEF /* XCRemoteSwiftPackageReference "Swift-JWK-to-PEM" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/ibm-cloud-security/Swift-JWK-to-PEM"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.4.0; - }; - }; - CE5D7A402620DA45001DFEEF /* XCRemoteSwiftPackageReference "BlueECC" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/Kitura/BlueECC"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.2.5; - }; - }; CEB78C55261F8DE100FB8F68 /* XCRemoteSwiftPackageReference "SwiftCBOR" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/unrelentingtech/SwiftCBOR"; @@ -646,16 +626,6 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - CE5D7A382620D6CA001DFEEF /* SwiftJWKtoPEM */ = { - isa = XCSwiftPackageProductDependency; - package = CE5D7A372620D6CA001DFEEF /* XCRemoteSwiftPackageReference "Swift-JWK-to-PEM" */; - productName = SwiftJWKtoPEM; - }; - CE5D7A412620DA45001DFEEF /* CryptorECC */ = { - isa = XCSwiftPackageProductDependency; - package = CE5D7A402620DA45001DFEEF /* XCRemoteSwiftPackageReference "BlueECC" */; - productName = CryptorECC; - }; CEB78C56261F8DE100FB8F68 /* SwiftCBOR */ = { isa = XCSwiftPackageProductDependency; package = CEB78C55261F8DE100FB8F68 /* XCRemoteSwiftPackageReference "SwiftCBOR" */; diff --git a/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..098e9a2 --- /dev/null +++ b/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PatientScannerDemo/JWK.swift b/PatientScannerDemo/JWK.swift new file mode 100644 index 0000000..558f47f --- /dev/null +++ b/PatientScannerDemo/JWK.swift @@ -0,0 +1,48 @@ +// +// JWK.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/13/21. +// +// https://medium.com/@vaibhav.pmeshram/creating-and-dismantling-ec-key-in-swift-f5bde8cb633f +// + +import Foundation + +struct JWK { + public func from(x: String, y: String) -> SecKey? { + var xStr = x // Base64 Formatted data + var yStr = y + + xStr = xStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/") + while xStr.count % 4 != 0 { + xStr.append("=") + } + yStr = yStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/") + while yStr.count % 4 != 0 { + yStr.append("=") + } + guard + let xBytes = Data(base64Encoded: xStr), + let yBytes = Data(base64Encoded: yStr) + else { return nil } + + // Now this bytes we have to append such that [0x04 , /* xBytes */, /* yBytes */, /* dBytes */] + // Initial byte for uncompressed y as Key. + let keyData = NSMutableData.init(bytes: [0x04], length: [0x04].count) + keyData.append(xBytes) + keyData.append(yBytes) + let attributes: [String: Any] = [ + kSecAttrKeyType as String: kSecAttrKeyTypeEC, + kSecAttrKeyClass as String: kSecAttrKeyClassPrivate, + kSecAttrKeySizeInBits as String: 256, + kSecAttrIsPermanent as String: false + ] + var error: Unmanaged? + guard + let keyReference = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, &error) + else { return nil } + + return keyReference + } +} diff --git a/PatientScannerDemo/ViewController.swift b/PatientScannerDemo/ViewController.swift index 5d46fe1..ac10aef 100644 --- a/PatientScannerDemo/ViewController.swift +++ b/PatientScannerDemo/ViewController.swift @@ -11,7 +11,6 @@ import UIKit import Vision import AVFoundation import SwiftCBOR -import SwiftJWKtoPEM //import CryptorECC @@ -178,9 +177,9 @@ extension ViewController { } """ - let key = try! RSAKey(jwk: keyString) - - let publicPem = try! key.getPublicKey() +// let key = try! RSAKey(jwk: keyString) +// +// let publicPem = try! key.getPublicKey() // let verifier = verifySignature(key: publicPem!.data(using: .utf8)!, signature: Data(signature), for: Data(payloadBytes)) // print(verifier) From f1799478b2af7b1126c9060fb1474f3e5c5723d7 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Tue, 13 Apr 2021 17:14:28 +0200 Subject: [PATCH 04/89] Reset project temporarily. --- PatientScannerDemo.xcodeproj/project.pbxproj | 45 +--------- .../xcshareddata/swiftpm/Package.resolved | 43 --------- .../xcdebugger/Breakpoints_v2.xcbkptlist | 88 ------------------- 3 files changed, 3 insertions(+), 173 deletions(-) delete mode 100644 PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved delete mode 100644 PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 3849fee..81b6a2c 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ @@ -15,10 +15,6 @@ CEA6D6F8261F8D2900715333 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */; }; CEA6D703261F8D2900715333 /* PatientScannerDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */; }; CEA6D70E261F8D2900715333 /* PatientScannerDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */; }; - CEB78C4A261F8DA200FB8F68 /* Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB78C48261F8DA200FB8F68 /* Base45.swift */; }; - CEB78C4B261F8DA200FB8F68 /* ZLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB78C49261F8DA200FB8F68 /* ZLib.swift */; }; - CEB78C57261F8DE100FB8F68 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CEB78C56261F8DE100FB8F68 /* SwiftCBOR */; }; - CED0DCFE2625DC0100CBB5CE /* JWK.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED0DCFD2625DC0100CBB5CE /* JWK.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -53,9 +49,6 @@ CEA6D709261F8D2900715333 /* PatientScannerDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PatientScannerDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatientScannerDemoUITests.swift; sourceTree = ""; }; CEA6D70F261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - CEB78C48261F8DA200FB8F68 /* Base45.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Base45.swift; sourceTree = ""; }; - CEB78C49261F8DA200FB8F68 /* ZLib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZLib.swift; sourceTree = ""; }; - CED0DCFD2625DC0100CBB5CE /* JWK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWK.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -63,7 +56,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - CEB78C57261F8DE100FB8F68 /* SwiftCBOR in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -107,8 +99,6 @@ CEA6D6EA261F8D2700715333 /* PatientScannerDemo */ = { isa = PBXGroup; children = ( - CEB78C48261F8DA200FB8F68 /* Base45.swift */, - CEB78C49261F8DA200FB8F68 /* ZLib.swift */, CEA6D6EB261F8D2700715333 /* AppDelegate.swift */, CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */, CEA6D6EF261F8D2700715333 /* ViewController.swift */, @@ -116,7 +106,6 @@ CEA6D6F4261F8D2900715333 /* Assets.xcassets */, CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */, CEA6D6F9261F8D2900715333 /* Info.plist */, - CED0DCFD2625DC0100CBB5CE /* JWK.swift */, ); path = PatientScannerDemo; sourceTree = ""; @@ -155,9 +144,6 @@ dependencies = ( ); name = PatientScannerDemo; - packageProductDependencies = ( - CEB78C56261F8DE100FB8F68 /* SwiftCBOR */, - ); productName = PatientScannerDemo; productReference = CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */; productType = "com.apple.product-type.application"; @@ -229,9 +215,6 @@ Base, ); mainGroup = CEA6D6DF261F8D2700715333; - packageReferences = ( - CEB78C55261F8DE100FB8F68 /* XCRemoteSwiftPackageReference "SwiftCBOR" */, - ); productRefGroup = CEA6D6E9261F8D2700715333 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -275,12 +258,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - CEB78C4B261F8DA200FB8F68 /* ZLib.swift in Sources */, CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, - CED0DCFE2625DC0100CBB5CE /* JWK.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */, - CEB78C4A261F8DA200FB8F68 /* Base45.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -386,7 +366,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; + IPHONEOS_DEPLOYMENT_TARGET = 14.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -441,7 +421,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; + IPHONEOS_DEPLOYMENT_TARGET = 14.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; @@ -613,25 +593,6 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - CEB78C55261F8DE100FB8F68 /* XCRemoteSwiftPackageReference "SwiftCBOR" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/unrelentingtech/SwiftCBOR"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.4.3; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - CEB78C56261F8DE100FB8F68 /* SwiftCBOR */ = { - isa = XCSwiftPackageProductDependency; - package = CEB78C55261F8DE100FB8F68 /* XCRemoteSwiftPackageReference "SwiftCBOR" */; - productName = SwiftCBOR; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = CEA6D6E0261F8D2700715333 /* Project object */; } diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 91582d9..0000000 --- a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,43 +0,0 @@ -{ - "object": { - "pins": [ - { - "package": "CryptorECC", - "repositoryURL": "https://github.com/Kitura/BlueECC", - "state": { - "branch": null, - "revision": "baf6ed3fc1a622675f0041b4aff7c02dd1a93818", - "version": "1.2.200" - } - }, - { - "package": "OpenSSL", - "repositoryURL": "https://github.com/IBM-Swift/OpenSSL.git", - "state": { - "branch": null, - "revision": "80b04f33b086fc90e28d9ae159d43705fb348e16", - "version": "2.2.200" - } - }, - { - "package": "SwiftJWKtoPEM", - "repositoryURL": "https://github.com/ibm-cloud-security/Swift-JWK-to-PEM", - "state": { - "branch": null, - "revision": "b18e2af1392bb84f1cde83b1e00847051c9fdda6", - "version": "0.4.0" - } - }, - { - "package": "SwiftCBOR", - "repositoryURL": "https://github.com/unrelentingtech/SwiftCBOR", - "state": { - "branch": null, - "revision": "668c26fc3373d5f1bccbaad7665ca6048797e324", - "version": "0.4.3" - } - } - ] - }, - "version": 1 -} diff --git a/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist deleted file mode 100644 index 098e9a2..0000000 --- a/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - From b0eb1bab692251b6da806dda63fc331b5f12588a Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Tue, 13 Apr 2021 17:25:30 +0200 Subject: [PATCH 05/89] Re-link existing code. --- PatientScannerDemo.xcodeproj/project.pbxproj | 41 ++++++++++++++++++- .../xcshareddata/swiftpm/Package.resolved | 16 ++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 81b6a2c..89d3447 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -3,10 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ + CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CE7DE7F92625EF18007E6694 /* SwiftCBOR */; }; CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EB261F8D2700715333 /* AppDelegate.swift */; }; CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */; }; CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EF261F8D2700715333 /* ViewController.swift */; }; @@ -15,6 +16,9 @@ CEA6D6F8261F8D2900715333 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */; }; CEA6D703261F8D2900715333 /* PatientScannerDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */; }; CEA6D70E261F8D2900715333 /* PatientScannerDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */; }; + CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4BF2625ED030056E406 /* ZLib.swift */; }; + CEC2C4C32625ED030056E406 /* JWK.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4C02625ED030056E406 /* JWK.swift */; }; + CEC2C4C42625ED030056E406 /* Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4C12625ED030056E406 /* Base45.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -49,6 +53,9 @@ CEA6D709261F8D2900715333 /* PatientScannerDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PatientScannerDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatientScannerDemoUITests.swift; sourceTree = ""; }; CEA6D70F261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CEC2C4BF2625ED030056E406 /* ZLib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZLib.swift; sourceTree = ""; }; + CEC2C4C02625ED030056E406 /* JWK.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JWK.swift; sourceTree = ""; }; + CEC2C4C12625ED030056E406 /* Base45.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Base45.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -56,6 +63,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -99,6 +107,9 @@ CEA6D6EA261F8D2700715333 /* PatientScannerDemo */ = { isa = PBXGroup; children = ( + CEC2C4C12625ED030056E406 /* Base45.swift */, + CEC2C4C02625ED030056E406 /* JWK.swift */, + CEC2C4BF2625ED030056E406 /* ZLib.swift */, CEA6D6EB261F8D2700715333 /* AppDelegate.swift */, CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */, CEA6D6EF261F8D2700715333 /* ViewController.swift */, @@ -144,6 +155,9 @@ dependencies = ( ); name = PatientScannerDemo; + packageProductDependencies = ( + CE7DE7F92625EF18007E6694 /* SwiftCBOR */, + ); productName = PatientScannerDemo; productReference = CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */; productType = "com.apple.product-type.application"; @@ -215,6 +229,9 @@ Base, ); mainGroup = CEA6D6DF261F8D2700715333; + packageReferences = ( + CE7DE7F82625EF18007E6694 /* XCRemoteSwiftPackageReference "SwiftCBOR" */, + ); productRefGroup = CEA6D6E9261F8D2700715333 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -258,8 +275,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CEC2C4C32625ED030056E406 /* JWK.swift in Sources */, + CEC2C4C42625ED030056E406 /* Base45.swift in Sources */, CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, + CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */, CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -593,6 +613,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + CE7DE7F82625EF18007E6694 /* XCRemoteSwiftPackageReference "SwiftCBOR" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/unrelentingtech/SwiftCBOR"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.4.3; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + CE7DE7F92625EF18007E6694 /* SwiftCBOR */ = { + isa = XCSwiftPackageProductDependency; + package = CE7DE7F82625EF18007E6694 /* XCRemoteSwiftPackageReference "SwiftCBOR" */; + productName = SwiftCBOR; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = CEA6D6E0261F8D2700715333 /* Project object */; } diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..bc6ed56 --- /dev/null +++ b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "SwiftCBOR", + "repositoryURL": "https://github.com/unrelentingtech/SwiftCBOR", + "state": { + "branch": null, + "revision": "668c26fc3373d5f1bccbaad7665ca6048797e324", + "version": "0.4.3" + } + } + ] + }, + "version": 1 +} From db108dd17eb0c7ffb7ed4893dc68d510d5c62040 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Tue, 13 Apr 2021 17:44:39 +0200 Subject: [PATCH 06/89] First attempt at verifying signature. --- PatientScannerDemo.xcodeproj/project.pbxproj | 8 +++ PatientScannerDemo/EC256.swift | 67 ++++++++++++++++++++ PatientScannerDemo/JWK.swift | 2 +- PatientScannerDemo/String+JSON.swift | 22 +++++++ PatientScannerDemo/ViewController.swift | 10 +++ 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 PatientScannerDemo/EC256.swift create mode 100644 PatientScannerDemo/String+JSON.swift diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 89d3447..eaffd4a 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -19,6 +19,8 @@ CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4BF2625ED030056E406 /* ZLib.swift */; }; CEC2C4C32625ED030056E406 /* JWK.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4C02625ED030056E406 /* JWK.swift */; }; CEC2C4C42625ED030056E406 /* Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4C12625ED030056E406 /* Base45.swift */; }; + CEFAD86D2625F164009AFEF9 /* EC256.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD86C2625F164009AFEF9 /* EC256.swift */; }; + CEFAD8722625F29E009AFEF9 /* String+JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD8712625F29E009AFEF9 /* String+JSON.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -56,6 +58,8 @@ CEC2C4BF2625ED030056E406 /* ZLib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZLib.swift; sourceTree = ""; }; CEC2C4C02625ED030056E406 /* JWK.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JWK.swift; sourceTree = ""; }; CEC2C4C12625ED030056E406 /* Base45.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Base45.swift; sourceTree = ""; }; + CEFAD86C2625F164009AFEF9 /* EC256.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EC256.swift; sourceTree = ""; }; + CEFAD8712625F29E009AFEF9 /* String+JSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+JSON.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -107,6 +111,7 @@ CEA6D6EA261F8D2700715333 /* PatientScannerDemo */ = { isa = PBXGroup; children = ( + CEFAD8712625F29E009AFEF9 /* String+JSON.swift */, CEC2C4C12625ED030056E406 /* Base45.swift */, CEC2C4C02625ED030056E406 /* JWK.swift */, CEC2C4BF2625ED030056E406 /* ZLib.swift */, @@ -117,6 +122,7 @@ CEA6D6F4261F8D2900715333 /* Assets.xcassets */, CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */, CEA6D6F9261F8D2900715333 /* Info.plist */, + CEFAD86C2625F164009AFEF9 /* EC256.swift */, ); path = PatientScannerDemo; sourceTree = ""; @@ -278,7 +284,9 @@ CEC2C4C32625ED030056E406 /* JWK.swift in Sources */, CEC2C4C42625ED030056E406 /* Base45.swift in Sources */, CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, + CEFAD86D2625F164009AFEF9 /* EC256.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, + CEFAD8722625F29E009AFEF9 /* String+JSON.swift in Sources */, CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */, CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */, ); diff --git a/PatientScannerDemo/EC256.swift b/PatientScannerDemo/EC256.swift new file mode 100644 index 0000000..d620818 --- /dev/null +++ b/PatientScannerDemo/EC256.swift @@ -0,0 +1,67 @@ +// +// EC256.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/13/21. +// +// https://developer.apple.com/forums/thread/83136 +// + +import Foundation + +struct EC256 { + public static func verify(signature: Data, for data: Data, with publicKey: SecKey) -> Bool { + // create a certificate object +// let certURL = URL(fileURLWithPath: #file).appendingPathComponent("../../../cert.der").standardized +// let certData = NSData(contentsOf: certURL) + var error: Unmanaged? + +// +// // create a SecCertificate object +// +// var secCertificate: SecCertificate? +// +// if let certData = certData { +// secCertificate = SecCertificateCreateWithData(nil, certData) +// } +// +// // create a SecTrust object +// var trustCert: SecTrust? +// let secTrustError = SecTrustCreateWithCertificates(secCertificate!, nil, &trustCert) +// guard secTrustError == errSecSuccess else { +// return false +// } + + // read in OpenSSL generated signature + +// let openSSLSigURL = URL(fileURLWithPath: #file).appendingPathComponent("../../../signature.bin").standardized + let openSSLSig = signature + + + guard +// let trustCert = trustCert, + let targetsSignedData = data as NSData? + else { return false } + + // obtain public key from SecTrust object +// let publicKey = SecTrustCopyPublicKey(trustCert) + + // ensure key is of the correct algorithm + + guard SecKeyIsAlgorithmSupported(publicKey, .verify, SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256) else { + return false + } + + // verify signature + if SecKeyVerifySignature(publicKey, SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256, targetsSignedData, openSSLSig as NSData, &error) { + print("Verify Success!") + return true + } + else { + print("Verify Failed!") + print(error.debugDescription) + return false + } + } +} + diff --git a/PatientScannerDemo/JWK.swift b/PatientScannerDemo/JWK.swift index 558f47f..27b3671 100644 --- a/PatientScannerDemo/JWK.swift +++ b/PatientScannerDemo/JWK.swift @@ -10,7 +10,7 @@ import Foundation struct JWK { - public func from(x: String, y: String) -> SecKey? { + public static func from(x: String, y: String) -> SecKey? { var xStr = x // Base64 Formatted data var yStr = y diff --git a/PatientScannerDemo/String+JSON.swift b/PatientScannerDemo/String+JSON.swift new file mode 100644 index 0000000..dc6414b --- /dev/null +++ b/PatientScannerDemo/String+JSON.swift @@ -0,0 +1,22 @@ +// +// File.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/13/21. +// + +import Foundation + +extension String { + var asJSONDict: [String: AnyObject] { + if let data = data(using: .utf8) { + do { + let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject] + return json ?? [:] + } catch { + return [:] + } + } + return [:] + } +} diff --git a/PatientScannerDemo/ViewController.swift b/PatientScannerDemo/ViewController.swift index ac10aef..addebc0 100644 --- a/PatientScannerDemo/ViewController.swift +++ b/PatientScannerDemo/ViewController.swift @@ -176,6 +176,16 @@ extension ViewController { "y": "bP7L_fysDzwFc13DDEPllO2qu1nDiDd1btoVQ-XlKok" } """ + let keyJWK = keyString.asJSONDict + + guard + let x = keyJWK["x"] as? String, + let y = keyJWK["y"] as? String, + let pubKey = JWK.from(x: x, y: y) + else { return } + + print(EC256.verify(signature: Data(signature), for: Data(payloadBytes), with: pubKey)) + // let key = try! RSAKey(jwk: keyString) // From 465461f586b5d06544e5808cbe9bbb48452974ef Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Tue, 13 Apr 2021 17:49:44 +0200 Subject: [PATCH 07/89] Print errors; Change key to public. --- PatientScannerDemo/EC256.swift | 2 +- PatientScannerDemo/JWK.swift | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/PatientScannerDemo/EC256.swift b/PatientScannerDemo/EC256.swift index d620818..4a9897c 100644 --- a/PatientScannerDemo/EC256.swift +++ b/PatientScannerDemo/EC256.swift @@ -59,7 +59,7 @@ struct EC256 { } else { print("Verify Failed!") - print(error.debugDescription) + print(error?.takeUnretainedValue().localizedDescription ?? "Something went wrong") return false } } diff --git a/PatientScannerDemo/JWK.swift b/PatientScannerDemo/JWK.swift index 27b3671..8e4ee92 100644 --- a/PatientScannerDemo/JWK.swift +++ b/PatientScannerDemo/JWK.swift @@ -34,14 +34,17 @@ struct JWK { keyData.append(yBytes) let attributes: [String: Any] = [ kSecAttrKeyType as String: kSecAttrKeyTypeEC, - kSecAttrKeyClass as String: kSecAttrKeyClassPrivate, + kSecAttrKeyClass as String: kSecAttrKeyClassPublic, kSecAttrKeySizeInBits as String: 256, kSecAttrIsPermanent as String: false ] var error: Unmanaged? guard let keyReference = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, &error) - else { return nil } + else { + print(error?.takeUnretainedValue().localizedDescription ?? "Something went wrong") + return nil + } return keyReference } From 1edab61086fb730aad45dcb84f39de8ae181c4ea Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Tue, 13 Apr 2021 17:57:50 +0200 Subject: [PATCH 08/89] Clean up EC256. --- PatientScannerDemo/EC256.swift | 49 +++++++--------------------------- 1 file changed, 10 insertions(+), 39 deletions(-) diff --git a/PatientScannerDemo/EC256.swift b/PatientScannerDemo/EC256.swift index 4a9897c..bb3d66b 100644 --- a/PatientScannerDemo/EC256.swift +++ b/PatientScannerDemo/EC256.swift @@ -11,54 +11,25 @@ import Foundation struct EC256 { public static func verify(signature: Data, for data: Data, with publicKey: SecKey) -> Bool { - // create a certificate object -// let certURL = URL(fileURLWithPath: #file).appendingPathComponent("../../../cert.der").standardized -// let certData = NSData(contentsOf: certURL) var error: Unmanaged? + let targetsSignedData = data as NSData -// -// // create a SecCertificate object -// -// var secCertificate: SecCertificate? -// -// if let certData = certData { -// secCertificate = SecCertificateCreateWithData(nil, certData) -// } -// -// // create a SecTrust object -// var trustCert: SecTrust? -// let secTrustError = SecTrustCreateWithCertificates(secCertificate!, nil, &trustCert) -// guard secTrustError == errSecSuccess else { -// return false -// } - - // read in OpenSSL generated signature - -// let openSSLSigURL = URL(fileURLWithPath: #file).appendingPathComponent("../../../signature.bin").standardized - let openSSLSig = signature - - - guard -// let trustCert = trustCert, - let targetsSignedData = data as NSData? - else { return false } - - // obtain public key from SecTrust object -// let publicKey = SecTrustCopyPublicKey(trustCert) - - // ensure key is of the correct algorithm - - guard SecKeyIsAlgorithmSupported(publicKey, .verify, SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256) else { + guard SecKeyIsAlgorithmSupported(publicKey, .verify, .ecdsaSignatureMessageX962SHA256) else { + print("Pubkey not supported.") return false } // verify signature - if SecKeyVerifySignature(publicKey, SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256, targetsSignedData, openSSLSig as NSData, &error) { - print("Verify Success!") + if SecKeyVerifySignature( + publicKey, + SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256, + targetsSignedData, + signature as NSData, + &error + ) { return true } else { - print("Verify Failed!") print(error?.takeUnretainedValue().localizedDescription ?? "Something went wrong") return false } From 4c9447285f4572adbc91c604ba35ce0e37454aea Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Wed, 14 Apr 2021 14:57:53 +0200 Subject: [PATCH 09/89] Add hexString methods; Clean up VC. --- PatientScannerDemo.xcodeproj/project.pbxproj | 12 ++++++++ PatientScannerDemo/Data+hexString.swift | 29 ++++++++++++++++++++ PatientScannerDemo/ViewController.swift | 10 ++++--- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 PatientScannerDemo/Data+hexString.swift diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index eaffd4a..c0ccf8b 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -21,6 +21,9 @@ CEC2C4C42625ED030056E406 /* Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4C12625ED030056E406 /* Base45.swift */; }; CEFAD86D2625F164009AFEF9 /* EC256.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD86C2625F164009AFEF9 /* EC256.swift */; }; CEFAD8722625F29E009AFEF9 /* String+JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD8712625F29E009AFEF9 /* String+JSON.swift */; }; + CEFAD87A26271414009AFEF9 /* COSE.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD87926271414009AFEF9 /* COSE.swift */; }; + CEFAD87F262714C4009AFEF9 /* EHNTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD87E262714C4009AFEF9 /* EHNTests.swift */; }; + CEFAD88726271B9A009AFEF9 /* Data+hexString.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,6 +63,9 @@ CEC2C4C12625ED030056E406 /* Base45.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Base45.swift; sourceTree = ""; }; CEFAD86C2625F164009AFEF9 /* EC256.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EC256.swift; sourceTree = ""; }; CEFAD8712625F29E009AFEF9 /* String+JSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+JSON.swift"; sourceTree = ""; }; + CEFAD87926271414009AFEF9 /* COSE.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = COSE.swift; sourceTree = ""; }; + CEFAD87E262714C4009AFEF9 /* EHNTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EHNTests.swift; sourceTree = ""; }; + CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+hexString.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -123,6 +129,8 @@ CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */, CEA6D6F9261F8D2900715333 /* Info.plist */, CEFAD86C2625F164009AFEF9 /* EC256.swift */, + CEFAD87926271414009AFEF9 /* COSE.swift */, + CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */, ); path = PatientScannerDemo; sourceTree = ""; @@ -132,6 +140,7 @@ children = ( CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */, CEA6D704261F8D2900715333 /* Info.plist */, + CEFAD87E262714C4009AFEF9 /* EHNTests.swift */, ); path = PatientScannerDemoTests; sourceTree = ""; @@ -281,9 +290,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CEFAD88726271B9A009AFEF9 /* Data+hexString.swift in Sources */, CEC2C4C32625ED030056E406 /* JWK.swift in Sources */, CEC2C4C42625ED030056E406 /* Base45.swift in Sources */, CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, + CEFAD87A26271414009AFEF9 /* COSE.swift in Sources */, CEFAD86D2625F164009AFEF9 /* EC256.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, CEFAD8722625F29E009AFEF9 /* String+JSON.swift in Sources */, @@ -297,6 +308,7 @@ buildActionMask = 2147483647; files = ( CEA6D703261F8D2900715333 /* PatientScannerDemoTests.swift in Sources */, + CEFAD87F262714C4009AFEF9 /* EHNTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PatientScannerDemo/Data+hexString.swift b/PatientScannerDemo/Data+hexString.swift new file mode 100644 index 0000000..00cdd59 --- /dev/null +++ b/PatientScannerDemo/Data+hexString.swift @@ -0,0 +1,29 @@ +// +// Data+hexString.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/14/21. +// + +import Foundation + +extension Data { + init?(hexString: String) { + let len = hexString.count / 2 + var data = Data(capacity: len) + var i = hexString.startIndex + for _ in 0.. Date: Wed, 14 Apr 2021 14:58:10 +0200 Subject: [PATCH 10/89] Add EHNTest by DWvG. --- PatientScannerDemoTests/EHNTests.swift | 142 +++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 PatientScannerDemoTests/EHNTests.swift diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift new file mode 100644 index 0000000..20fee87 --- /dev/null +++ b/PatientScannerDemoTests/EHNTests.swift @@ -0,0 +1,142 @@ +// +// EHNTests.swift +// EHNTests +// +// Created by Dirk-Willem van Gulik on 01/04/2021. +// + +@testable import PatientScannerDemo +import XCTest +import CryptoKit +import SwiftCBOR + +var barcode = "HC1NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5" + +let trust_json = """ +[ + { + \"kid\" : \"DEFBBA3378B322F5\", + \"coord\" : [ + \"230ca0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\", + \"bf1bfe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\" + ] + }, + { + \"kid\" : \"FFFBBA3378B322F5\", + \"coord\" : [ + \"9999a0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\", + \"9999fe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\" + ] + } +] +""" + + +class EHNTests: XCTestCase { + + func test_cose() throws { + let COSE_TAG = UInt64(18) + let COSE_PHDR_SIG = CBOR.unsignedInt(1) + let COSE_PHDR_KID = CBOR.unsignedInt(4) + + // Remove HC1 header if any + if (barcode.hasPrefix("HC1")) { + barcode = String(barcode.suffix(barcode.count-3)) + } + + guard + let compressed = try? barcode.fromBase45() + else { return } + + let data = decompress(compressed) + let decoder = SwiftCBOR.CBORDecoder(input: data.uint) + + guard + let cose = try? decoder.decodeItem(), + case let CBOR.tagged(tag, cborElement) = cose, + tag.rawValue == COSE_TAG, // SIGN1 + case let CBOR.array(array) = cborElement, + case let CBOR.byteString(protectedBytes) = array[0], + case let CBOR.map(unprotected) = array[1], + case let CBOR.byteString(payloadBytes) = array[2], + case let CBOR.byteString(signature) = array[3], + let protected = try? CBOR.decode(protectedBytes), + let payload = try? CBOR.decode(payloadBytes), + case let CBOR.map(protectedMap) = protected + else { + return + } + var kid: [UInt8] = [] + let sig = protectedMap[COSE_PHDR_SIG]! + + print("SIG: ", sig) + if case let CBOR.byteString(k) = protectedMap[COSE_PHDR_KID] ?? .null { + kid = k + } + + print("Signature: ", signature) + print("Payload: ", payload) + print("KID: ", kid) + + let externalData = CBOR.byteString([]) + let signed_payload: [UInt8] = CBOR.encode( + [ + "Signature1", + array[0], + externalData, + array[2] + ] + ) + let d = Data(bytes: signed_payload, count: signed_payload.count) + print("Signing: ", d.base64EncodedString()) + let digest = SHA256.hash(data: signed_payload) + print("Digest: ", digest) + + var publicKey: P256.Signing.PublicKey + let signatureForData = try! P256.Signing.ECDSASignature(rawRepresentation: signature) + + // use KID to find the right X,Y coordinates from the JSON + // + struct TE : CustomStringConvertible { + var description: String + let kid : String + //let coord : Array() + } + var x: [UInt8] = [] + var y: [UInt8] = [] + + let _ = unprotected // unused + + do { + if let trust = try JSONSerialization.jsonObject(with: trust_json.data(using: .utf8)!, options: []) as? [[String: Any]] { + for case let elem : Dictionary in trust { + if kid == Data(hexString: elem["kid"] as! String)?.uint { + print("We know this KID - check if this sig works...") + x = Data(hexString: ((elem["coord"] as! Array)[0] as? String) ?? "")?.uint ?? [] + y = Data(hexString: ((elem["coord"] as! Array)[1] as? String) ?? "")?.uint ?? [] + + var rawk: [UInt8] = [04] + rawk.append(contentsOf: x) + rawk.append(contentsOf: y) + XCTAssert(rawk.count == 32+32+1) + + publicKey = try! P256.Signing.PublicKey(x963Representation: rawk) + + if (publicKey.isValidSignature(signatureForData, for: digest)) { + print("All is WELL !") + + print("Payload (decoded)") + print(array[2]); + return + } + print("- sig failed - which is OK - we may have more matching KIDS --") + } + print("Nope - all failed - sadness all around") + assert(false) + } + } + } catch let error as NSError { + print("JSON parse trust list failed: ",error.localizedDescription) + } + } +} From 2329b18f1f32a746efa2655367666be7c704d99e Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Wed, 14 Apr 2021 16:02:10 +0200 Subject: [PATCH 11/89] Clean up test code. --- PatientScannerDemoTests/EHNTests.swift | 70 +++++++++++++++----------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index 20fee87..fcc69a7 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -46,7 +46,10 @@ class EHNTests: XCTestCase { guard let compressed = try? barcode.fromBase45() - else { return } + else { + assert(false) + return + } let data = decompress(compressed) let decoder = SwiftCBOR.CBORDecoder(input: data.uint) @@ -64,6 +67,7 @@ class EHNTests: XCTestCase { let payload = try? CBOR.decode(payloadBytes), case let CBOR.map(protectedMap) = protected else { + assert(false) return } var kid: [UInt8] = [] @@ -72,6 +76,8 @@ class EHNTests: XCTestCase { print("SIG: ", sig) if case let CBOR.byteString(k) = protectedMap[COSE_PHDR_KID] ?? .null { kid = k + } else { + assert(false) } print("Signature: ", signature) @@ -92,7 +98,6 @@ class EHNTests: XCTestCase { let digest = SHA256.hash(data: signed_payload) print("Digest: ", digest) - var publicKey: P256.Signing.PublicKey let signatureForData = try! P256.Signing.ECDSASignature(rawRepresentation: signature) // use KID to find the right X,Y coordinates from the JSON @@ -107,36 +112,43 @@ class EHNTests: XCTestCase { let _ = unprotected // unused - do { - if let trust = try JSONSerialization.jsonObject(with: trust_json.data(using: .utf8)!, options: []) as? [[String: Any]] { - for case let elem : Dictionary in trust { - if kid == Data(hexString: elem["kid"] as! String)?.uint { - print("We know this KID - check if this sig works...") - x = Data(hexString: ((elem["coord"] as! Array)[0] as? String) ?? "")?.uint ?? [] - y = Data(hexString: ((elem["coord"] as! Array)[1] as? String) ?? "")?.uint ?? [] - - var rawk: [UInt8] = [04] - rawk.append(contentsOf: x) - rawk.append(contentsOf: y) - XCTAssert(rawk.count == 32+32+1) - - publicKey = try! P256.Signing.PublicKey(x963Representation: rawk) - - if (publicKey.isValidSignature(signatureForData, for: digest)) { - print("All is WELL !") - - print("Payload (decoded)") - print(array[2]); - return - } - print("- sig failed - which is OK - we may have more matching KIDS --") + if let trust = try? JSONSerialization.jsonObject(with: trust_json.data(using: .utf8)!, options: []) as? [[String: Any]] { + for case let elem: Dictionary in trust { + if kid == Data(hexString: elem["kid"] as! String)?.uint { + print("We know this KID - check if this sig works...") + x = Data(hexString: ((elem["coord"] as! Array)[0] as? String) ?? "")?.uint ?? [] + y = Data(hexString: ((elem["coord"] as! Array)[1] as? String) ?? "")?.uint ?? [] + + var rawk: [UInt8] = [04] + rawk.append(contentsOf: x) + rawk.append(contentsOf: y) + XCTAssert(rawk.count == 32+32+1) + + if + let publicKey = try? P256.Signing.PublicKey(x963Representation: rawk), + publicKey.isValidSignature(signatureForData, for: digest) + { + print("All is WELL !") + + print("Payload (decoded)") + print(array[2]) + return } - print("Nope - all failed - sadness all around") - assert(false) + print("- sig failed - which is OK - we may have more matching KIDS --") } + print("Nope - all failed - sadness all around") + assert(false) } - } catch let error as NSError { - print("JSON parse trust list failed: ",error.localizedDescription) } } } + +/** + + Produces: + + All is WELL ! + Payload (decoded) + byteString([161, 99, 102, 111, 111, 99, 98, 97, 114]) + + */ From 5a632a344e1a8f147f3d2711c42609d589e47650 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Wed, 14 Apr 2021 16:37:28 +0200 Subject: [PATCH 12/89] Add COSE Service. --- PatientScannerDemo/COSE.swift | 69 ++++++++++++++++ PatientScannerDemoTests/EHNTests.swift | 107 +++++++------------------ 2 files changed, 99 insertions(+), 77 deletions(-) create mode 100644 PatientScannerDemo/COSE.swift diff --git a/PatientScannerDemo/COSE.swift b/PatientScannerDemo/COSE.swift new file mode 100644 index 0000000..73d15ba --- /dev/null +++ b/PatientScannerDemo/COSE.swift @@ -0,0 +1,69 @@ +// +// COSE.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/14/21. +// + +import Foundation +import SwiftCBOR +import CryptoKit + +struct COSE { + public static func verify(_ cbor: CBOR, with xHex: String, and yHex: String) -> Bool { + let COSE_TAG = UInt64(18) + let COSE_PHDR_SIG = CBOR.unsignedInt(1) + + guard + case let CBOR.tagged(tag, cborElement) = cbor, + tag.rawValue == COSE_TAG, // SIGN1 + case let CBOR.array(array) = cborElement, + case let CBOR.byteString(protectedBytes) = array[0], + case let CBOR.map(unprotected) = array[1], + case let CBOR.byteString(payloadBytes) = array[2], + case let CBOR.byteString(signature) = array[3], + let protected = try? CBOR.decode(protectedBytes), + let payload = try? CBOR.decode(payloadBytes), + case let CBOR.map(protectedMap) = protected, + let sig = protectedMap[COSE_PHDR_SIG] + else { + return false + } + + let signedPayload: [UInt8] = CBOR.encode( + [ + "Signature1", + array[0], + CBOR.byteString([]), + array[2] + ] + ) + let d = Data(bytes: signedPayload, count: signedPayload.count) + let digest = SHA256.hash(data: signedPayload) + guard + let signatureForData = try? P256.Signing.ECDSASignature(rawRepresentation: signature) + else { + return false + } + + struct TE : CustomStringConvertible { + var description: String + let kid : String + //let coord : Array() + } + + let x = Data(hexString: xHex)?.uint ?? [] + let y = Data(hexString: yHex)?.uint ?? [] + let rawk: [UInt8] = [04] + x + y + let _ = (unprotected, sig, d, payload) // unused + + if + rawk.count == 32+32+1, + let publicKey = try? P256.Signing.PublicKey(x963Representation: rawk), + publicKey.isValidSignature(signatureForData, for: digest) + { + return true + } + return false + } +} diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index fcc69a7..92b07f7 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -12,7 +12,7 @@ import SwiftCBOR var barcode = "HC1NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5" -let trust_json = """ +let trustJson = """ [ { \"kid\" : \"DEFBBA3378B322F5\", @@ -33,10 +33,8 @@ let trust_json = """ class EHNTests: XCTestCase { - func test_cose() throws { let COSE_TAG = UInt64(18) - let COSE_PHDR_SIG = CBOR.unsignedInt(1) let COSE_PHDR_KID = CBOR.unsignedInt(4) // Remove HC1 header if any @@ -47,7 +45,7 @@ class EHNTests: XCTestCase { guard let compressed = try? barcode.fromBase45() else { - assert(false) + XCTAssert(false) return } @@ -55,91 +53,48 @@ class EHNTests: XCTestCase { let decoder = SwiftCBOR.CBORDecoder(input: data.uint) guard - let cose = try? decoder.decodeItem(), - case let CBOR.tagged(tag, cborElement) = cose, + let cbor = try? decoder.decodeItem(), + case let CBOR.tagged(tag, cborElement) = cbor, tag.rawValue == COSE_TAG, // SIGN1 case let CBOR.array(array) = cborElement, case let CBOR.byteString(protectedBytes) = array[0], - case let CBOR.map(unprotected) = array[1], case let CBOR.byteString(payloadBytes) = array[2], - case let CBOR.byteString(signature) = array[3], let protected = try? CBOR.decode(protectedBytes), let payload = try? CBOR.decode(payloadBytes), case let CBOR.map(protectedMap) = protected else { - assert(false) + XCTAssert(false) return } - var kid: [UInt8] = [] - let sig = protectedMap[COSE_PHDR_SIG]! - - print("SIG: ", sig) - if case let CBOR.byteString(k) = protectedMap[COSE_PHDR_KID] ?? .null { - kid = k - } else { - assert(false) + guard case let CBOR.byteString(kid) = protectedMap[COSE_PHDR_KID] ?? .null else { + XCTAssert(false) + return } - print("Signature: ", signature) - print("Payload: ", payload) - print("KID: ", kid) - - let externalData = CBOR.byteString([]) - let signed_payload: [UInt8] = CBOR.encode( - [ - "Signature1", - array[0], - externalData, - array[2] - ] - ) - let d = Data(bytes: signed_payload, count: signed_payload.count) - print("Signing: ", d.base64EncodedString()) - let digest = SHA256.hash(data: signed_payload) - print("Digest: ", digest) - - let signatureForData = try! P256.Signing.ECDSASignature(rawRepresentation: signature) - - // use KID to find the right X,Y coordinates from the JSON - // - struct TE : CustomStringConvertible { - var description: String - let kid : String - //let coord : Array() + guard + let trustData = trustJson.data(using: .utf8), + let trustSerialization = try? JSONSerialization.jsonObject(with: trustData, options: []), + let trust = trustSerialization as? [[String: Any]] + else { + XCTAssert(false) + return } - var x: [UInt8] = [] - var y: [UInt8] = [] - - let _ = unprotected // unused - - if let trust = try? JSONSerialization.jsonObject(with: trust_json.data(using: .utf8)!, options: []) as? [[String: Any]] { - for case let elem: Dictionary in trust { - if kid == Data(hexString: elem["kid"] as! String)?.uint { - print("We know this KID - check if this sig works...") - x = Data(hexString: ((elem["coord"] as! Array)[0] as? String) ?? "")?.uint ?? [] - y = Data(hexString: ((elem["coord"] as! Array)[1] as? String) ?? "")?.uint ?? [] - - var rawk: [UInt8] = [04] - rawk.append(contentsOf: x) - rawk.append(contentsOf: y) - XCTAssert(rawk.count == 32+32+1) - - if - let publicKey = try? P256.Signing.PublicKey(x963Representation: rawk), - publicKey.isValidSignature(signatureForData, for: digest) - { - print("All is WELL !") - - print("Payload (decoded)") - print(array[2]) - return - } - print("- sig failed - which is OK - we may have more matching KIDS --") + for case let elem: Dictionary in trust { + if + kid == Data(hexString: elem["kid"] as! String)?.uint, + let x = (elem["coord"] as? Array)?[0] as? String, + let y = (elem["coord"] as? Array)?[1] as? String + { + print("We know this KID - check if this sig works...") + if COSE.verify(cbor, with: x, and: y) { + print("All is well! Payload: ", payload) + return } - print("Nope - all failed - sadness all around") - assert(false) + print("- sig failed - which is OK - we may have more matching KIDS --") } } + print("Nope - all failed - sadness all around") + XCTAssert(false) } } @@ -147,8 +102,6 @@ class EHNTests: XCTestCase { Produces: - All is WELL ! - Payload (decoded) - byteString([161, 99, 102, 111, 111, 99, 98, 97, 114]) - + All is well! Payload: map([SwiftCBOR.CBOR.utf8String("foo"): SwiftCBOR.CBOR.utf8String("bar")]) + */ From 74e80f6b824b600fd83f35cdc488a33fe500b068 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 15 Apr 2021 00:31:30 +0200 Subject: [PATCH 13/89] Remove unneeded struct. --- PatientScannerDemo/COSE.swift | 6 ------ 1 file changed, 6 deletions(-) diff --git a/PatientScannerDemo/COSE.swift b/PatientScannerDemo/COSE.swift index 73d15ba..66ddd81 100644 --- a/PatientScannerDemo/COSE.swift +++ b/PatientScannerDemo/COSE.swift @@ -46,12 +46,6 @@ struct COSE { return false } - struct TE : CustomStringConvertible { - var description: String - let kid : String - //let coord : Array() - } - let x = Data(hexString: xHex)?.uint ?? [] let y = Data(hexString: yHex)?.uint ?? [] let rawk: [UInt8] = [04] + x + y From 1ee4bc51eeed3e0dd918782ed171fe5444f20f9c Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 15 Apr 2021 18:59:30 +0200 Subject: [PATCH 14/89] Add Asn1Encoder. --- PatientScannerDemo/Asn1Encoder.swift | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 PatientScannerDemo/Asn1Encoder.swift diff --git a/PatientScannerDemo/Asn1Encoder.swift b/PatientScannerDemo/Asn1Encoder.swift new file mode 100644 index 0000000..4085186 --- /dev/null +++ b/PatientScannerDemo/Asn1Encoder.swift @@ -0,0 +1,34 @@ +// +// Asn1Encoder.swift +// OegvatClient +// +// Created by Christian Kollmann on 23.04.20. +// + +import Foundation + +public class Asn1Encoder { + + public init() {} + + // 32 for ES256 + public func convertRawSignatureIntoAsn1(_ data: Data, _ digestLengthInBytes: Int = 32) -> Data { + let sigR = encodeIntegerToAsn1(data.prefix(data.count - digestLengthInBytes)) + let sigS = encodeIntegerToAsn1(data.suffix(digestLengthInBytes)) + let tagSequence: UInt8 = 0x30 + return Data([tagSequence] + [UInt8(sigR.count + sigS.count)] + sigR + sigS) + } + + private func encodeIntegerToAsn1(_ data: Data) -> Data { + let firstBitIsSet: UInt8 = 0x80 // would be decoded as a negative number + let tagInteger: UInt8 = 0x02 + if (data.first! >= firstBitIsSet) { + return Data([tagInteger] + [UInt8(data.count + 1)] + [0x00] + data) + } else if (data.first! == 0x00) { + return encodeIntegerToAsn1(data.dropFirst()) + } else { + return Data([tagInteger] + [UInt8(data.count)] + data) + } + } + +} From 96c7896ea90cbf5dfc2d65fae1ce170571910902 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 15 Apr 2021 19:02:12 +0200 Subject: [PATCH 15/89] Abandon CryptoKit. --- PatientScannerDemo.xcodeproj/project.pbxproj | 4 ++ .../{Asn1Encoder.swift => ASN1.swift} | 9 +-- PatientScannerDemo/COSE.swift | 36 +++--------- PatientScannerDemo/EC256.swift | 31 +++++----- PatientScannerDemo/JWK.swift | 58 +++++++++++-------- PatientScannerDemo/ViewController.swift | 2 +- PatientScannerDemoTests/EHNTests.swift | 43 +++++++------- 7 files changed, 84 insertions(+), 99 deletions(-) rename PatientScannerDemo/{Asn1Encoder.swift => ASN1.swift} (79%) diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index c0ccf8b..619ec16 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC93B2628A7820079FB78 /* ASN1.swift */; }; CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CE7DE7F92625EF18007E6694 /* SwiftCBOR */; }; CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EB261F8D2700715333 /* AppDelegate.swift */; }; CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */; }; @@ -44,6 +45,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + CE3CC93B2628A7820079FB78 /* ASN1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASN1.swift; sourceTree = ""; }; CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PatientScannerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; CEA6D6EB261F8D2700715333 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -129,6 +131,7 @@ CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */, CEA6D6F9261F8D2900715333 /* Info.plist */, CEFAD86C2625F164009AFEF9 /* EC256.swift */, + CE3CC93B2628A7820079FB78 /* ASN1.swift */, CEFAD87926271414009AFEF9 /* COSE.swift */, CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */, ); @@ -294,6 +297,7 @@ CEC2C4C32625ED030056E406 /* JWK.swift in Sources */, CEC2C4C42625ED030056E406 /* Base45.swift in Sources */, CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, + CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */, CEFAD87A26271414009AFEF9 /* COSE.swift in Sources */, CEFAD86D2625F164009AFEF9 /* EC256.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, diff --git a/PatientScannerDemo/Asn1Encoder.swift b/PatientScannerDemo/ASN1.swift similarity index 79% rename from PatientScannerDemo/Asn1Encoder.swift rename to PatientScannerDemo/ASN1.swift index 4085186..badc02d 100644 --- a/PatientScannerDemo/Asn1Encoder.swift +++ b/PatientScannerDemo/ASN1.swift @@ -7,19 +7,16 @@ import Foundation -public class Asn1Encoder { - - public init() {} - +public class ASN1 { // 32 for ES256 - public func convertRawSignatureIntoAsn1(_ data: Data, _ digestLengthInBytes: Int = 32) -> Data { + public static func signature(from data: Data, _ digestLengthInBytes: Int = 32) -> Data { let sigR = encodeIntegerToAsn1(data.prefix(data.count - digestLengthInBytes)) let sigS = encodeIntegerToAsn1(data.suffix(digestLengthInBytes)) let tagSequence: UInt8 = 0x30 return Data([tagSequence] + [UInt8(sigR.count + sigS.count)] + sigR + sigS) } - private func encodeIntegerToAsn1(_ data: Data) -> Data { + private static func encodeIntegerToAsn1(_ data: Data) -> Data { let firstBitIsSet: UInt8 = 0x80 // would be decoded as a negative number let tagInteger: UInt8 = 0x02 if (data.first! >= firstBitIsSet) { diff --git a/PatientScannerDemo/COSE.swift b/PatientScannerDemo/COSE.swift index 66ddd81..3afe71b 100644 --- a/PatientScannerDemo/COSE.swift +++ b/PatientScannerDemo/COSE.swift @@ -7,25 +7,17 @@ import Foundation import SwiftCBOR -import CryptoKit +//import CryptoKit struct COSE { public static func verify(_ cbor: CBOR, with xHex: String, and yHex: String) -> Bool { let COSE_TAG = UInt64(18) - let COSE_PHDR_SIG = CBOR.unsignedInt(1) guard case let CBOR.tagged(tag, cborElement) = cbor, tag.rawValue == COSE_TAG, // SIGN1 case let CBOR.array(array) = cborElement, - case let CBOR.byteString(protectedBytes) = array[0], - case let CBOR.map(unprotected) = array[1], - case let CBOR.byteString(payloadBytes) = array[2], - case let CBOR.byteString(signature) = array[3], - let protected = try? CBOR.decode(protectedBytes), - let payload = try? CBOR.decode(payloadBytes), - case let CBOR.map(protectedMap) = protected, - let sig = protectedMap[COSE_PHDR_SIG] + case let CBOR.byteString(signature) = array[3] else { return false } @@ -38,26 +30,12 @@ struct COSE { array[2] ] ) - let d = Data(bytes: signedPayload, count: signedPayload.count) - let digest = SHA256.hash(data: signedPayload) - guard - let signatureForData = try? P256.Signing.ECDSASignature(rawRepresentation: signature) - else { + let d = Data(signedPayload)//Data(bytes: signedPayload, count: signedPayload.count) +// let digest = SHA256.hash(data: signedPayload) + let s = Data(signature)//Data(bytes: signature, count: signature.count) + guard let key = JWK.ecFrom(x: xHex, y: yHex) else { return false } - - let x = Data(hexString: xHex)?.uint ?? [] - let y = Data(hexString: yHex)?.uint ?? [] - let rawk: [UInt8] = [04] + x + y - let _ = (unprotected, sig, d, payload) // unused - - if - rawk.count == 32+32+1, - let publicKey = try? P256.Signing.PublicKey(x963Representation: rawk), - publicKey.isValidSignature(signatureForData, for: digest) - { - return true - } - return false + return EC256.verify(signature: s, for: d, with: key) } } diff --git a/PatientScannerDemo/EC256.swift b/PatientScannerDemo/EC256.swift index bb3d66b..55e6ece 100644 --- a/PatientScannerDemo/EC256.swift +++ b/PatientScannerDemo/EC256.swift @@ -11,28 +11,27 @@ import Foundation struct EC256 { public static func verify(signature: Data, for data: Data, with publicKey: SecKey) -> Bool { - var error: Unmanaged? - let targetsSignedData = data as NSData - guard SecKeyIsAlgorithmSupported(publicKey, .verify, .ecdsaSignatureMessageX962SHA256) else { print("Pubkey not supported.") return false } + let sig = ASN1.signature(from: signature) + // verify signature - if SecKeyVerifySignature( - publicKey, - SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256, - targetsSignedData, - signature as NSData, - &error - ) { - return true - } - else { - print(error?.takeUnretainedValue().localizedDescription ?? "Something went wrong") - return false + var error: Unmanaged? + let result = SecKeyVerifySignature( + publicKey, + .ecdsaSignatureMessageX962SHA256, + data as NSData, + sig as NSData, + &error + ) + if let err = error?.takeUnretainedValue().localizedDescription { + print(err) } + error?.release() + + return result } } - diff --git a/PatientScannerDemo/JWK.swift b/PatientScannerDemo/JWK.swift index 8e4ee92..fb7adba 100644 --- a/PatientScannerDemo/JWK.swift +++ b/PatientScannerDemo/JWK.swift @@ -10,42 +10,50 @@ import Foundation struct JWK { - public static func from(x: String, y: String) -> SecKey? { - var xStr = x // Base64 Formatted data - var yStr = y + public static func ecFrom(x: String, y: String) -> SecKey? { + var xBytes: Data? + var yBytes: Data? + if (x + y).count == 128 { + xBytes = Data(hexString: x) + yBytes = Data(hexString: y) + } else { + var xStr = x // Base64 Formatted data + var yStr = y - xStr = xStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/") - while xStr.count % 4 != 0 { - xStr.append("=") + xStr = xStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/") + while xStr.count % 4 != 0 { + xStr.append("=") + } + yStr = yStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/") + while yStr.count % 4 != 0 { + yStr.append("=") + } + xBytes = Data(base64Encoded: xStr) + yBytes = Data(base64Encoded: yStr) } - yStr = yStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/") - while yStr.count % 4 != 0 { - yStr.append("=") - } - guard - let xBytes = Data(base64Encoded: xStr), - let yBytes = Data(base64Encoded: yStr) - else { return nil } - // Now this bytes we have to append such that [0x04 , /* xBytes */, /* yBytes */, /* dBytes */] + // Now this bytes we have to append such that [0x04 , /* xBytes */, /* yBytes */] // Initial byte for uncompressed y as Key. - let keyData = NSMutableData.init(bytes: [0x04], length: [0x04].count) - keyData.append(xBytes) - keyData.append(yBytes) + let keyData = NSMutableData.init(bytes: [0x04], length: 1) + keyData.append(xBytes ?? Data()) + keyData.append(yBytes ?? Data()) let attributes: [String: Any] = [ - kSecAttrKeyType as String: kSecAttrKeyTypeEC, - kSecAttrKeyClass as String: kSecAttrKeyClassPublic, - kSecAttrKeySizeInBits as String: 256, - kSecAttrIsPermanent as String: false + String(kSecAttrKeyType): kSecAttrKeyTypeEC, + String(kSecAttrKeyClass): kSecAttrKeyClassPublic, + String(kSecAttrKeySizeInBits): 256, + String(kSecAttrIsPermanent): false ] var error: Unmanaged? + let keyReference = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, &error) + let errorString = error?.takeUnretainedValue().localizedDescription ?? "Something went wrong" + error?.release() guard - let keyReference = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, &error) + let key = keyReference else { - print(error?.takeUnretainedValue().localizedDescription ?? "Something went wrong") + print(errorString) return nil } - return keyReference + return key } } diff --git a/PatientScannerDemo/ViewController.swift b/PatientScannerDemo/ViewController.swift index e6422c1..8306eab 100644 --- a/PatientScannerDemo/ViewController.swift +++ b/PatientScannerDemo/ViewController.swift @@ -183,7 +183,7 @@ extension ViewController { guard let x = keyJWK["x"] as? String, let y = keyJWK["y"] as? String, - let pubKey = JWK.from(x: x, y: y) + let pubKey = JWK.ecFrom(x: x, y: y) else { return } print(EC256.verify(signature: Data(signature), for: Data(payloadBytes), with: pubKey)) diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index 92b07f7..e275320 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -10,30 +10,29 @@ import XCTest import CryptoKit import SwiftCBOR -var barcode = "HC1NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5" - -let trustJson = """ -[ - { - \"kid\" : \"DEFBBA3378B322F5\", - \"coord\" : [ - \"230ca0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\", - \"bf1bfe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\" - ] - }, - { - \"kid\" : \"FFFBBA3378B322F5\", - \"coord\" : [ - \"9999a0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\", - \"9999fe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\" - ] - } -] -""" - - class EHNTests: XCTestCase { func test_cose() throws { + + var barcode = "HC1NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5" + + let trustJson = """ + [ + { + \"kid\" : \"DEFBBA3378B322F5\", + \"coord\" : [ + \"230ca0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\", + \"bf1bfe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\" + ] + }, + { + \"kid\" : \"FFFBBA3378B322F5\", + \"coord\" : [ + \"9999a0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\", + \"9999fe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\" + ] + } + ] + """ let COSE_TAG = UInt64(18) let COSE_PHDR_KID = CBOR.unsignedInt(4) From b430e5606b8791283ceff44682d6e8cf74efc29e Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 15 Apr 2021 20:55:32 +0200 Subject: [PATCH 16/89] Clean up code. --- PatientScannerDemo.xcodeproj/project.pbxproj | 4 ++ PatientScannerDemo/Base45.swift | 2 +- PatientScannerDemo/CBOR.swift | 48 ++++++++++++++++ PatientScannerDemo/COSE.swift | 26 +++++---- PatientScannerDemo/ViewController.swift | 60 +------------------- PatientScannerDemoTests/EHNTests.swift | 29 ++-------- 6 files changed, 74 insertions(+), 95 deletions(-) create mode 100644 PatientScannerDemo/CBOR.swift diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 619ec16..72e86a0 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC93B2628A7820079FB78 /* ASN1.swift */; }; + CE3CC9442628C2130079FB78 /* CBOR.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC9432628C2130079FB78 /* CBOR.swift */; }; CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CE7DE7F92625EF18007E6694 /* SwiftCBOR */; }; CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EB261F8D2700715333 /* AppDelegate.swift */; }; CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */; }; @@ -46,6 +47,7 @@ /* Begin PBXFileReference section */ CE3CC93B2628A7820079FB78 /* ASN1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASN1.swift; sourceTree = ""; }; + CE3CC9432628C2130079FB78 /* CBOR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBOR.swift; sourceTree = ""; }; CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PatientScannerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; CEA6D6EB261F8D2700715333 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -134,6 +136,7 @@ CE3CC93B2628A7820079FB78 /* ASN1.swift */, CEFAD87926271414009AFEF9 /* COSE.swift */, CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */, + CE3CC9432628C2130079FB78 /* CBOR.swift */, ); path = PatientScannerDemo; sourceTree = ""; @@ -296,6 +299,7 @@ CEFAD88726271B9A009AFEF9 /* Data+hexString.swift in Sources */, CEC2C4C32625ED030056E406 /* JWK.swift in Sources */, CEC2C4C42625ED030056E406 /* Base45.swift in Sources */, + CE3CC9442628C2130079FB78 /* CBOR.swift in Sources */, CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */, CEFAD87A26271414009AFEF9 /* COSE.swift in Sources */, diff --git a/PatientScannerDemo/Base45.swift b/PatientScannerDemo/Base45.swift index a4453ef..a9ea3e1 100644 --- a/PatientScannerDemo/Base45.swift +++ b/PatientScannerDemo/Base45.swift @@ -1,9 +1,9 @@ // // Base45.swift -// Base45-Swift // // Created by Dirk-Willem van Gulik on 01/04/2021. // + import Foundation extension String { diff --git a/PatientScannerDemo/CBOR.swift b/PatientScannerDemo/CBOR.swift new file mode 100644 index 0000000..2bb19ba --- /dev/null +++ b/PatientScannerDemo/CBOR.swift @@ -0,0 +1,48 @@ +// +// CBOR.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/15/21. +// + +import Foundation +import SwiftCBOR + +struct CBOR { + public static func payload(from data: Data) -> SwiftCBOR.CBOR? { + let COSE_TAG = UInt64(18) + let decoder = SwiftCBOR.CBORDecoder(input: data.uint) + + guard + let cbor = try? decoder.decodeItem(), + case let SwiftCBOR.CBOR.tagged(tag, cborElement) = cbor, + tag.rawValue == COSE_TAG, // SIGN1 + case let SwiftCBOR.CBOR.array(array) = cborElement, + case let SwiftCBOR.CBOR.byteString(payloadBytes) = array[2], + let payload = try? SwiftCBOR.CBOR.decode(payloadBytes) + else { + return nil + } + return payload + } + + public static func kid(from data: Data) -> [UInt8]? { + let COSE_TAG = UInt64(18) + let COSE_PHDR_KID = SwiftCBOR.CBOR.unsignedInt(4) + let decoder = SwiftCBOR.CBORDecoder(input: data.uint) + + guard + let cbor = try? decoder.decodeItem(), + case let SwiftCBOR.CBOR.tagged(tag, cborElement) = cbor, + tag.rawValue == COSE_TAG, // SIGN1 + case let SwiftCBOR.CBOR.array(array) = cborElement, + case let SwiftCBOR.CBOR.byteString(protectedBytes) = array[0], + let protected = try? SwiftCBOR.CBOR.decode(protectedBytes), + case let SwiftCBOR.CBOR.map(protectedMap) = protected, + case let SwiftCBOR.CBOR.byteString(kid) = protectedMap[COSE_PHDR_KID] ?? .null + else { + return nil + } + return kid + } +} diff --git a/PatientScannerDemo/COSE.swift b/PatientScannerDemo/COSE.swift index 3afe71b..6e470d9 100644 --- a/PatientScannerDemo/COSE.swift +++ b/PatientScannerDemo/COSE.swift @@ -7,32 +7,38 @@ import Foundation import SwiftCBOR -//import CryptoKit struct COSE { - public static func verify(_ cbor: CBOR, with xHex: String, and yHex: String) -> Bool { + public static func verify(_ cborData: Data, with xHex: String, and yHex: String) -> Bool { + let decoder = SwiftCBOR.CBORDecoder(input: cborData.uint) + + guard let cbor = try? decoder.decodeItem() else { + return false + } + return verify(cbor, with: xHex, and: yHex) + } + public static func verify(_ cbor: SwiftCBOR.CBOR, with xHex: String, and yHex: String) -> Bool { let COSE_TAG = UInt64(18) guard - case let CBOR.tagged(tag, cborElement) = cbor, + case let SwiftCBOR.CBOR.tagged(tag, cborElement) = cbor, tag.rawValue == COSE_TAG, // SIGN1 - case let CBOR.array(array) = cborElement, - case let CBOR.byteString(signature) = array[3] + case let SwiftCBOR.CBOR.array(array) = cborElement, + case let SwiftCBOR.CBOR.byteString(signature) = array[3] else { return false } - let signedPayload: [UInt8] = CBOR.encode( + let signedPayload: [UInt8] = SwiftCBOR.CBOR.encode( [ "Signature1", array[0], - CBOR.byteString([]), + SwiftCBOR.CBOR.byteString([]), array[2] ] ) - let d = Data(signedPayload)//Data(bytes: signedPayload, count: signedPayload.count) -// let digest = SHA256.hash(data: signedPayload) - let s = Data(signature)//Data(bytes: signature, count: signature.count) + let d = Data(signedPayload) + let s = Data(signature) guard let key = JWK.ecFrom(x: xHex, y: yHex) else { return false } diff --git a/PatientScannerDemo/ViewController.swift b/PatientScannerDemo/ViewController.swift index 8306eab..8d99795 100644 --- a/PatientScannerDemo/ViewController.swift +++ b/PatientScannerDemo/ViewController.swift @@ -135,66 +135,8 @@ extension ViewController { else { return } let data = decompress(compressed) - var s = "" - for char in data { - s += String(data: Data([char]), encoding: .utf8) ?? "?" - } - - print(data) - let decoder = SwiftCBOR.CBORDecoder(input: data.uint) - guard - let cose = try? decoder.decodeItem(), - case let CBOR.tagged(tag, cborElement) = cose, - tag.rawValue == 18, // SIGN1 - case let CBOR.array(array) = cborElement, - case let CBOR.byteString(protectedBytes) = array[0], - case let CBOR.map(unprotected) = array[1], - case let CBOR.byteString(payloadBytes) = array[2], - case let CBOR.byteString(signature) = array[3], - let protected = try? CBOR.decode(protectedBytes), - let payload = try? CBOR.decode(payloadBytes), - case let CBOR.map(protectedMap) = protected - else { - return - } - - print("START") - print(protected) - print(protectedMap) - print(unprotected) - print(payload) - print(signature) - print("END") - print() - print() - // print(s) - - let keyString = """ -{ - "crv": "P-256", - "kid": "MklRdnVDMEdIZ29EeVY5VHo2WDR5MGlHTFNCZTgxdE5iN2wzYTZsUElCUQ", - "kty": "EC", - "x": "DHJudz6lqcTXizpz4cb_bbi8NZ9ofoD3lYnvByrMfLc", - "y": "bP7L_fysDzwFc13DDEPllO2qu1nDiDd1btoVQ-XlKok" -} -""" - let keyJWK = keyString.asJSONDict - - guard - let x = keyJWK["x"] as? String, - let y = keyJWK["y"] as? String, - let pubKey = JWK.ecFrom(x: x, y: y) - else { return } - - print(EC256.verify(signature: Data(signature), for: Data(payloadBytes), with: pubKey)) - - -// let key = try! RSAKey(jwk: keyString) -// -// let publicPem = try! key.getPublicKey() -// let verifier = verifySignature(key: publicPem!.data(using: .utf8)!, signature: Data(signature), for: Data(payloadBytes)) -// print(verifier) + /// TODO } diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index e275320..55218be 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -7,8 +7,7 @@ @testable import PatientScannerDemo import XCTest -import CryptoKit -import SwiftCBOR + class EHNTests: XCTestCase { func test_cose() throws { @@ -33,8 +32,6 @@ class EHNTests: XCTestCase { } ] """ - let COSE_TAG = UInt64(18) - let COSE_PHDR_KID = CBOR.unsignedInt(4) // Remove HC1 header if any if (barcode.hasPrefix("HC1")) { @@ -49,28 +46,10 @@ class EHNTests: XCTestCase { } let data = decompress(compressed) - let decoder = SwiftCBOR.CBORDecoder(input: data.uint) - - guard - let cbor = try? decoder.decodeItem(), - case let CBOR.tagged(tag, cborElement) = cbor, - tag.rawValue == COSE_TAG, // SIGN1 - case let CBOR.array(array) = cborElement, - case let CBOR.byteString(protectedBytes) = array[0], - case let CBOR.byteString(payloadBytes) = array[2], - let protected = try? CBOR.decode(protectedBytes), - let payload = try? CBOR.decode(payloadBytes), - case let CBOR.map(protectedMap) = protected - else { - XCTAssert(false) - return - } - guard case let CBOR.byteString(kid) = protectedMap[COSE_PHDR_KID] ?? .null else { - XCTAssert(false) - return - } guard + let payload = CBOR.payload(from: data), + let kid = CBOR.kid(from: data), let trustData = trustJson.data(using: .utf8), let trustSerialization = try? JSONSerialization.jsonObject(with: trustData, options: []), let trust = trustSerialization as? [[String: Any]] @@ -85,7 +64,7 @@ class EHNTests: XCTestCase { let y = (elem["coord"] as? Array)?[1] as? String { print("We know this KID - check if this sig works...") - if COSE.verify(cbor, with: x, and: y) { + if COSE.verify(data, with: x, and: y) { print("All is well! Payload: ", payload) return } From 6b69ae3940f010b33aa3e2cc65442c290ec4e4e6 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Fri, 16 Apr 2021 17:00:00 +0200 Subject: [PATCH 17/89] Simplify zlib. --- PatientScannerDemo/ZLib.swift | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/PatientScannerDemo/ZLib.swift b/PatientScannerDemo/ZLib.swift index 8c40f53..46e9abe 100644 --- a/PatientScannerDemo/ZLib.swift +++ b/PatientScannerDemo/ZLib.swift @@ -4,15 +4,7 @@ import Foundation import Compression func decompressString(_ data: Data) -> String { - let size = 4 * data.count - let buffer = UnsafeMutablePointer.allocate(capacity: size) - let result = data.subdata(in: 2 ..< data.count).withUnsafeBytes ({ - let read = compression_decode_buffer(buffer, size, $0.baseAddress!.bindMemory(to: UInt8.self, capacity: 1), - data.count - 2, nil, COMPRESSION_ZLIB) - return String(decoding: Data(bytes: buffer, count:read), as: UTF8.self) - }) as String - buffer.deallocate() - return result + return String(decoding: decompress(data), as: UTF8.self) } func decompress(_ data: Data) -> Data { From 4ac7ccba11d57359c2efc677af8a608ee9a18107 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Fri, 16 Apr 2021 17:00:13 +0200 Subject: [PATCH 18/89] Support utf8 KID. --- PatientScannerDemo/CBOR.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/PatientScannerDemo/CBOR.swift b/PatientScannerDemo/CBOR.swift index 2bb19ba..ca7395f 100644 --- a/PatientScannerDemo/CBOR.swift +++ b/PatientScannerDemo/CBOR.swift @@ -38,11 +38,18 @@ struct CBOR { case let SwiftCBOR.CBOR.array(array) = cborElement, case let SwiftCBOR.CBOR.byteString(protectedBytes) = array[0], let protected = try? SwiftCBOR.CBOR.decode(protectedBytes), - case let SwiftCBOR.CBOR.map(protectedMap) = protected, - case let SwiftCBOR.CBOR.byteString(kid) = protectedMap[COSE_PHDR_KID] ?? .null + case let SwiftCBOR.CBOR.map(protectedMap) = protected else { return nil } - return kid + let kid = protectedMap[COSE_PHDR_KID] ?? .null + switch kid { + case let .utf8String(str): + return str.encode() + case let .byteString(str): + return str + default: + return nil + } } } From e5e29df5d6408b57903945fe4597dd91cb872652 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Fri, 16 Apr 2021 19:50:53 +0200 Subject: [PATCH 19/89] Enlarge zip buffer. --- PatientScannerDemo/ZLib.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PatientScannerDemo/ZLib.swift b/PatientScannerDemo/ZLib.swift index 46e9abe..6eed4cc 100644 --- a/PatientScannerDemo/ZLib.swift +++ b/PatientScannerDemo/ZLib.swift @@ -8,7 +8,7 @@ func decompressString(_ data: Data) -> String { } func decompress(_ data: Data) -> Data { - let size = 4 * data.count + let size = 4 * data.count + 8 * 1024 let buffer = UnsafeMutablePointer.allocate(capacity: size) let result = data.subdata(in: 2 ..< data.count).withUnsafeBytes ({ let read = compression_decode_buffer(buffer, size, $0.baseAddress!.bindMemory(to: UInt8.self, capacity: 1), From b2d3d41e06be36bbf5a563dd74229e81f0534a10 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Fri, 16 Apr 2021 19:51:10 +0200 Subject: [PATCH 20/89] Only support byte arrays as KID in production. --- PatientScannerDemo/CBOR.swift | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/PatientScannerDemo/CBOR.swift b/PatientScannerDemo/CBOR.swift index ca7395f..91173f7 100644 --- a/PatientScannerDemo/CBOR.swift +++ b/PatientScannerDemo/CBOR.swift @@ -45,9 +45,14 @@ struct CBOR { let kid = protectedMap[COSE_PHDR_KID] ?? .null switch kid { case let .utf8String(str): - return str.encode() - case let .byteString(str): - return str + #if DEBUG + print("Warning, CBOR not fully compliant!!") + #else + return nil + #endif + return Data(hexString: str)?.uint + case let .byteString(uint): + return uint default: return nil } From 2d3337b7c1fffb8e2f136792e362c16d10a50ad0 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Fri, 16 Apr 2021 21:57:05 +0200 Subject: [PATCH 21/89] Add kid fallback. --- PatientScannerDemo/CBOR.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PatientScannerDemo/CBOR.swift b/PatientScannerDemo/CBOR.swift index 91173f7..ceb750b 100644 --- a/PatientScannerDemo/CBOR.swift +++ b/PatientScannerDemo/CBOR.swift @@ -46,11 +46,11 @@ struct CBOR { switch kid { case let .utf8String(str): #if DEBUG - print("Warning, CBOR not fully compliant!!") + print("Warning, CBOR not fully compliant!! Trying to understand it as Hex String. Fallback utf8 (which is against the spec).") #else return nil #endif - return Data(hexString: str)?.uint + return Data(hexString: str)?.uint ?? str.encode() case let .byteString(uint): return uint default: From 72258606335dd23726e256e0ab0be6cf7159e1dd Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Sat, 17 Apr 2021 01:12:03 +0200 Subject: [PATCH 22/89] Add RSA support. --- PatientScannerDemo.xcodeproj/project.pbxproj | 12 ++- PatientScannerDemo/CBOR.swift | 2 +- PatientScannerDemo/COSE.swift | 37 +++++++- PatientScannerDemo/EC256.swift | 37 -------- PatientScannerDemo/Signature.swift | 60 +++++++++++++ PatientScannerDemo/X509.swift | 21 +++++ PatientScannerDemoTests/EHNTests.swift | 93 +++++++++++++++++++- 7 files changed, 217 insertions(+), 45 deletions(-) delete mode 100644 PatientScannerDemo/EC256.swift create mode 100644 PatientScannerDemo/Signature.swift create mode 100644 PatientScannerDemo/X509.swift diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 72e86a0..7f197b0 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + CE1BDF99262A4CD600766F97 /* X509.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1BDF98262A4CD600766F97 /* X509.swift */; }; CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC93B2628A7820079FB78 /* ASN1.swift */; }; CE3CC9442628C2130079FB78 /* CBOR.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC9432628C2130079FB78 /* CBOR.swift */; }; CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CE7DE7F92625EF18007E6694 /* SwiftCBOR */; }; @@ -21,7 +22,7 @@ CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4BF2625ED030056E406 /* ZLib.swift */; }; CEC2C4C32625ED030056E406 /* JWK.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4C02625ED030056E406 /* JWK.swift */; }; CEC2C4C42625ED030056E406 /* Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4C12625ED030056E406 /* Base45.swift */; }; - CEFAD86D2625F164009AFEF9 /* EC256.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD86C2625F164009AFEF9 /* EC256.swift */; }; + CEFAD86D2625F164009AFEF9 /* Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD86C2625F164009AFEF9 /* Signature.swift */; }; CEFAD8722625F29E009AFEF9 /* String+JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD8712625F29E009AFEF9 /* String+JSON.swift */; }; CEFAD87A26271414009AFEF9 /* COSE.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD87926271414009AFEF9 /* COSE.swift */; }; CEFAD87F262714C4009AFEF9 /* EHNTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD87E262714C4009AFEF9 /* EHNTests.swift */; }; @@ -46,6 +47,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + CE1BDF98262A4CD600766F97 /* X509.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = X509.swift; sourceTree = ""; }; CE3CC93B2628A7820079FB78 /* ASN1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASN1.swift; sourceTree = ""; }; CE3CC9432628C2130079FB78 /* CBOR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBOR.swift; sourceTree = ""; }; CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PatientScannerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -65,7 +67,7 @@ CEC2C4BF2625ED030056E406 /* ZLib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZLib.swift; sourceTree = ""; }; CEC2C4C02625ED030056E406 /* JWK.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JWK.swift; sourceTree = ""; }; CEC2C4C12625ED030056E406 /* Base45.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Base45.swift; sourceTree = ""; }; - CEFAD86C2625F164009AFEF9 /* EC256.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EC256.swift; sourceTree = ""; }; + CEFAD86C2625F164009AFEF9 /* Signature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signature.swift; sourceTree = ""; }; CEFAD8712625F29E009AFEF9 /* String+JSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+JSON.swift"; sourceTree = ""; }; CEFAD87926271414009AFEF9 /* COSE.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = COSE.swift; sourceTree = ""; }; CEFAD87E262714C4009AFEF9 /* EHNTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EHNTests.swift; sourceTree = ""; }; @@ -132,11 +134,12 @@ CEA6D6F4261F8D2900715333 /* Assets.xcassets */, CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */, CEA6D6F9261F8D2900715333 /* Info.plist */, - CEFAD86C2625F164009AFEF9 /* EC256.swift */, + CEFAD86C2625F164009AFEF9 /* Signature.swift */, CE3CC93B2628A7820079FB78 /* ASN1.swift */, CEFAD87926271414009AFEF9 /* COSE.swift */, CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */, CE3CC9432628C2130079FB78 /* CBOR.swift */, + CE1BDF98262A4CD600766F97 /* X509.swift */, ); path = PatientScannerDemo; sourceTree = ""; @@ -300,10 +303,11 @@ CEC2C4C32625ED030056E406 /* JWK.swift in Sources */, CEC2C4C42625ED030056E406 /* Base45.swift in Sources */, CE3CC9442628C2130079FB78 /* CBOR.swift in Sources */, + CE1BDF99262A4CD600766F97 /* X509.swift in Sources */, CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */, CEFAD87A26271414009AFEF9 /* COSE.swift in Sources */, - CEFAD86D2625F164009AFEF9 /* EC256.swift in Sources */, + CEFAD86D2625F164009AFEF9 /* Signature.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, CEFAD8722625F29E009AFEF9 /* String+JSON.swift in Sources */, CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */, diff --git a/PatientScannerDemo/CBOR.swift b/PatientScannerDemo/CBOR.swift index ceb750b..02ae8b2 100644 --- a/PatientScannerDemo/CBOR.swift +++ b/PatientScannerDemo/CBOR.swift @@ -50,7 +50,7 @@ struct CBOR { #else return nil #endif - return Data(hexString: str)?.uint ?? str.encode() + return Data(hexString: str)?.uint ?? str.data(using: .utf8)?.uint case let .byteString(uint): return uint default: diff --git a/PatientScannerDemo/COSE.swift b/PatientScannerDemo/COSE.swift index 6e470d9..5977616 100644 --- a/PatientScannerDemo/COSE.swift +++ b/PatientScannerDemo/COSE.swift @@ -17,6 +17,14 @@ struct COSE { } return verify(cbor, with: xHex, and: yHex) } + public static func verify(_ cborData: Data, with rsa: String) -> Bool { + let decoder = SwiftCBOR.CBORDecoder(input: cborData.uint) + + guard let cbor = try? decoder.decodeItem() else { + return false + } + return verify(cbor, with: rsa) + } public static func verify(_ cbor: SwiftCBOR.CBOR, with xHex: String, and yHex: String) -> Bool { let COSE_TAG = UInt64(18) @@ -42,6 +50,33 @@ struct COSE { guard let key = JWK.ecFrom(x: xHex, y: yHex) else { return false } - return EC256.verify(signature: s, for: d, with: key) + return Signature.verify(s, for: d, with: key) + } + public static func verify(_ cbor: SwiftCBOR.CBOR, with rsa: String) -> Bool { + let COSE_TAG = UInt64(18) + + guard + case let SwiftCBOR.CBOR.tagged(tag, cborElement) = cbor, + tag.rawValue == COSE_TAG, // SIGN1 + case let SwiftCBOR.CBOR.array(array) = cborElement, + case let SwiftCBOR.CBOR.byteString(signature) = array[3] + else { + return false + } + + let signedPayload: [UInt8] = SwiftCBOR.CBOR.encode( + [ + "Signature1", + array[0], + SwiftCBOR.CBOR.byteString([]), + array[2] + ] + ) + let d = Data(signedPayload) + let s = Data(signature) + guard let key = X509.rsa(from: rsa) else { + return false + } + return Signature.verify(s, for: d, with: key) } } diff --git a/PatientScannerDemo/EC256.swift b/PatientScannerDemo/EC256.swift deleted file mode 100644 index 55e6ece..0000000 --- a/PatientScannerDemo/EC256.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// EC256.swift -// PatientScannerDemo -// -// Created by Yannick Spreen on 4/13/21. -// -// https://developer.apple.com/forums/thread/83136 -// - -import Foundation - -struct EC256 { - public static func verify(signature: Data, for data: Data, with publicKey: SecKey) -> Bool { - guard SecKeyIsAlgorithmSupported(publicKey, .verify, .ecdsaSignatureMessageX962SHA256) else { - print("Pubkey not supported.") - return false - } - - let sig = ASN1.signature(from: signature) - - // verify signature - var error: Unmanaged? - let result = SecKeyVerifySignature( - publicKey, - .ecdsaSignatureMessageX962SHA256, - data as NSData, - sig as NSData, - &error - ) - if let err = error?.takeUnretainedValue().localizedDescription { - print(err) - } - error?.release() - - return result - } -} diff --git a/PatientScannerDemo/Signature.swift b/PatientScannerDemo/Signature.swift new file mode 100644 index 0000000..467decb --- /dev/null +++ b/PatientScannerDemo/Signature.swift @@ -0,0 +1,60 @@ +// +// EC256.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/13/21. +// +// https://developer.apple.com/forums/thread/83136 +// + +import Foundation + +struct Signature { + public static func verify(_ signature: Data, for data: Data, with publicKey: SecKey) -> Bool { + if SecKeyIsAlgorithmSupported(publicKey, .verify, .ecdsaSignatureMessageX962SHA256) { + return verifyEC(signature, for: data, with: publicKey) + } + if SecKeyIsAlgorithmSupported(publicKey, .verify, .rsaSignatureMessagePSSSHA256) { + return verifyRSA(signature, for: data, with: publicKey) + } + return false + } + + static func verifyEC(_ signature: Data, for data: Data, with publicKey: SecKey) -> Bool { + let sig = ASN1.signature(from: signature) + + var error: Unmanaged? + let result = SecKeyVerifySignature( + publicKey, + .ecdsaSignatureMessageX962SHA256, + data as NSData, + sig as NSData, + &error + ) + if let err = error?.takeUnretainedValue().localizedDescription { + print(err) + } + error?.release() + + return result + } + + static func verifyRSA(_ signature: Data, for data: Data, with publicKey: SecKey) -> Bool { + let sig = signature + + var error: Unmanaged? + let result = SecKeyVerifySignature( + publicKey, + .rsaSignatureMessagePSSSHA256, + data as NSData, + sig as NSData, + &error + ) + if let err = error?.takeUnretainedValue().localizedDescription { + print(err) + } + error?.release() + + return result + } +} diff --git a/PatientScannerDemo/X509.swift b/PatientScannerDemo/X509.swift new file mode 100644 index 0000000..a8c37e0 --- /dev/null +++ b/PatientScannerDemo/X509.swift @@ -0,0 +1,21 @@ +// +// X509.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/17/21. +// + +import Foundation + +struct X509 { + public static func rsa(from encodedCert: String) -> SecKey? { + guard + let encodedCertData = Data(base64Encoded: encodedCert), + let cert = SecCertificateCreateWithData(nil, encodedCertData as CFData), + let publicKey = SecCertificateCopyKey(cert) + else { + return nil + } + return publicKey + } +} diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index 55218be..1295814 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -10,8 +10,7 @@ import XCTest class EHNTests: XCTestCase { - func test_cose() throws { - + func testCoseEcdsa() throws { var barcode = "HC1NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5" let trustJson = """ @@ -74,6 +73,96 @@ class EHNTests: XCTestCase { print("Nope - all failed - sadness all around") XCTAssert(false) } + func testCoseATCose() throws { + var barcode = "HC1NCFI.L3B6AP2YQ2%MNBCHC51/CAOZDL+OL7S99U60SVOGSHD%24R4PCTH7Y9KL6EVJBIMBL364D X1KKLZ*I9K4RLDR7B011EROZS6022WR5VX4QG9W72HWCC12B:TWZG.%N8GWBCOV0O%5F9U7H 8P4L.%2/:6TXB/-J6ZJ.*QYIBYSD6/T.6RDMMK0PX6HTPO1REO*CWMFG5CJ38+FBS+8DB9*2FFP9Z8HEM137CRBQ.893$I.R7 DRFOVMUQRVDP4IU613/G-0LZ:43+MM:QO.CQPJU21-7PJ*L/*DVLO:Q5G-7%WF4ZO*JJR:KH+O1707M6.73VXG0+0050+IMIFH:3V+DL3JK/21/LEI$T5TUT8P:40P10AXGBRS%-GZS8TGF-IT3-HU2SVJUAVG%AGO98R00Y.QT23DVP0TB*-J6YJP 8TU9U/OJSQGGMK+K3MH IR U7H%9/UU07AGEWMVTOBAYIV4SPGC2Y5FJJ67I4/J4FXM3GP:SAOZQJPL%WGP4BT59Q8K5MB*M44%K9JTWB9K+LS-2I9ST+3J%0X%1YGN0E0KL3/FHTZHEF9WIC4Q1HVK74L186BWT9+TJR7C2M%9JXN8S%0PVU8GFBET%0PG RR1KD2F11G-CW8A4124N9VN-T-:292AX*B%ER*$12-O:6K:/N$ 7IYFFXQ/5F NC49M/W5501B2OKU7E:NHMM8SETWUK*I$JR" + + // Remove HC1 header if any + if (barcode.hasPrefix("HC1")) { + barcode = String(barcode.suffix(barcode.count-3)) + } + + guard + let compressed = try? barcode.fromBase45() + else { + XCTAssert(false) + return + } + + let data = decompress(compressed) + + guard + let kidBytes = CBOR.kid(from: data), + let kid = String(data: Data(kidBytes), encoding: .utf8), + let url = URL(string: "https://dev.a-sit.at/certservice/cert/\(kid)") + else { + XCTAssert(false) + return + } + let expectation = XCTestExpectation(description: "Download PubKey") + URLSession.shared.dataTask(with: URLRequest(url: url)) { body, response, error in + guard + error == nil, + let status = (response as? HTTPURLResponse)?.statusCode, + 200 == status, + let body = body + else { + XCTAssert(false) + return + } + let encodedCert = body.base64EncodedString() + if COSE.verify(data, with: encodedCert) { + expectation.fulfill() + } else { + XCTAssert(false) + } + }.resume() + wait(for: [expectation], timeout: 15) + } + func testCoseATRsa() throws { + var barcode = "HC1NCFI.LUZB.P2YQ2E R002$DLTLIYXM/+0JNEAFUP.CV5GKCL /A0SQT/O8ZA85D0IJ$5D4.J+MR8-EGK6DM1R58V1ERUCWM4.E4ZM4$WG O E6KX9$KHCQMFE0B$KPKA*A2+ELQ*5ZQE/*1ZMSM5S.:KGQ33LQOWN67QW68LXM867D6837QCWEU*E*OKZCJPSCPIM1:Q83FBODLRD/W8K$E4 SG4P2JM6GCMU9FFSZAKNJH6ZNZVSWU78MHB4TO5J0N51U2F:17AB8O0*N0CQSA-9VIN904*STT$6R1LLXDT8J1ZN4I4368L02N72ZMGV496.0NO3OQCPFVF+C$BKQH1$+8L:AAEGRIB548B68D/3-ZTZ.JNM84E0F59$N6DY2*6FACA448900U42ZEMMO7-LO.45*IMXYIODF:82RN4L8Q%20HDJ-YCHIA1YT87A2/C1NO1F6DPCLCK9+BDXEEK23JH0/I8XJQEQ1T8BQ5GNDRFPQKKV6WT$A+98TIOUSAFA0J8OMY87$P-LESPS1KO+:O%HOY*C8XH4ZE7D16QR WNN$EP:U7E2HTLS023X0GJBW887LCKVHDGJ+Q88I0A73$H6R30XYH-LDC$4+24*JSE*H98A471BJ3:R0LU3MZA+ 4/GMZ9J D4E7L.TI$L8L:TN4G2S552748V$%D0CPH9RJ-7Z4AXFN*SS/ZC44O3P5%%AE936OUSR1H7WP%CP8KQUCY9I%A5FDBV+0A%HPVP5SKP9TKAFKT9FYROAABDBEHVQ9317O0D7MS5Z.Q2+K2.1RGGS3B5OTO2ROD60Z6LE98E94TV09JXM395VA0N.98EP3*4E5SHA7I96Q70UF74SPSIJI.BUHQJ$:K$9M51H9Z6RPHR.K-XT855UJJZC8C*MSITGMRE%O+:JQXV$LS7SJ1:DE LCX7RP7T JH4RR-NK.PASIWKA8J5Z1NA*BE7KFTJXO4BM5QVF.S0-5CG8KQWB8RCA1VP*1Q.ELZ1Q21G.JEGLOFH1:FR09$SCY/OGBU1QIE/2 9SK3" + + // Remove HC1 header if any + if (barcode.hasPrefix("HC1")) { + barcode = String(barcode.suffix(barcode.count-3)) + } + + guard + let compressed = try? barcode.fromBase45() + else { + XCTAssert(false) + return + } + + let data = decompress(compressed) + + guard + let kidBytes = CBOR.kid(from: data), + let kid = String(data: Data(kidBytes), encoding: .utf8), + let url = URL(string: "https://dev.a-sit.at/certservice/cert/\(kid)") + else { + XCTAssert(false) + return + } + let expectation = XCTestExpectation(description: "Download PubKey") + URLSession.shared.dataTask(with: URLRequest(url: url)) { body, response, error in + guard + error == nil, + let status = (response as? HTTPURLResponse)?.statusCode, + 200 == status, + let body = body + else { + XCTAssert(false) + return + } + let encodedCert = body.base64EncodedString() + if COSE.verify(data, with: encodedCert) { + expectation.fulfill() + } else { + XCTAssert(false) + } + }.resume() + wait(for: [expectation], timeout: 15) + } } /** From ad3838a391fc936b802a9937a4fbf0917f436627 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Sat, 17 Apr 2021 01:18:02 +0200 Subject: [PATCH 23/89] Fix names. --- PatientScannerDemoTests/EHNTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index 1295814..1de7cd4 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -73,7 +73,7 @@ class EHNTests: XCTestCase { print("Nope - all failed - sadness all around") XCTAssert(false) } - func testCoseATCose() throws { + func testCoseEcAT() throws { var barcode = "HC1NCFI.L3B6AP2YQ2%MNBCHC51/CAOZDL+OL7S99U60SVOGSHD%24R4PCTH7Y9KL6EVJBIMBL364D X1KKLZ*I9K4RLDR7B011EROZS6022WR5VX4QG9W72HWCC12B:TWZG.%N8GWBCOV0O%5F9U7H 8P4L.%2/:6TXB/-J6ZJ.*QYIBYSD6/T.6RDMMK0PX6HTPO1REO*CWMFG5CJ38+FBS+8DB9*2FFP9Z8HEM137CRBQ.893$I.R7 DRFOVMUQRVDP4IU613/G-0LZ:43+MM:QO.CQPJU21-7PJ*L/*DVLO:Q5G-7%WF4ZO*JJR:KH+O1707M6.73VXG0+0050+IMIFH:3V+DL3JK/21/LEI$T5TUT8P:40P10AXGBRS%-GZS8TGF-IT3-HU2SVJUAVG%AGO98R00Y.QT23DVP0TB*-J6YJP 8TU9U/OJSQGGMK+K3MH IR U7H%9/UU07AGEWMVTOBAYIV4SPGC2Y5FJJ67I4/J4FXM3GP:SAOZQJPL%WGP4BT59Q8K5MB*M44%K9JTWB9K+LS-2I9ST+3J%0X%1YGN0E0KL3/FHTZHEF9WIC4Q1HVK74L186BWT9+TJR7C2M%9JXN8S%0PVU8GFBET%0PG RR1KD2F11G-CW8A4124N9VN-T-:292AX*B%ER*$12-O:6K:/N$ 7IYFFXQ/5F NC49M/W5501B2OKU7E:NHMM8SETWUK*I$JR" // Remove HC1 header if any @@ -118,7 +118,7 @@ class EHNTests: XCTestCase { }.resume() wait(for: [expectation], timeout: 15) } - func testCoseATRsa() throws { + func testCoseRsaAT() throws { var barcode = "HC1NCFI.LUZB.P2YQ2E R002$DLTLIYXM/+0JNEAFUP.CV5GKCL /A0SQT/O8ZA85D0IJ$5D4.J+MR8-EGK6DM1R58V1ERUCWM4.E4ZM4$WG O E6KX9$KHCQMFE0B$KPKA*A2+ELQ*5ZQE/*1ZMSM5S.:KGQ33LQOWN67QW68LXM867D6837QCWEU*E*OKZCJPSCPIM1:Q83FBODLRD/W8K$E4 SG4P2JM6GCMU9FFSZAKNJH6ZNZVSWU78MHB4TO5J0N51U2F:17AB8O0*N0CQSA-9VIN904*STT$6R1LLXDT8J1ZN4I4368L02N72ZMGV496.0NO3OQCPFVF+C$BKQH1$+8L:AAEGRIB548B68D/3-ZTZ.JNM84E0F59$N6DY2*6FACA448900U42ZEMMO7-LO.45*IMXYIODF:82RN4L8Q%20HDJ-YCHIA1YT87A2/C1NO1F6DPCLCK9+BDXEEK23JH0/I8XJQEQ1T8BQ5GNDRFPQKKV6WT$A+98TIOUSAFA0J8OMY87$P-LESPS1KO+:O%HOY*C8XH4ZE7D16QR WNN$EP:U7E2HTLS023X0GJBW887LCKVHDGJ+Q88I0A73$H6R30XYH-LDC$4+24*JSE*H98A471BJ3:R0LU3MZA+ 4/GMZ9J D4E7L.TI$L8L:TN4G2S552748V$%D0CPH9RJ-7Z4AXFN*SS/ZC44O3P5%%AE936OUSR1H7WP%CP8KQUCY9I%A5FDBV+0A%HPVP5SKP9TKAFKT9FYROAABDBEHVQ9317O0D7MS5Z.Q2+K2.1RGGS3B5OTO2ROD60Z6LE98E94TV09JXM395VA0N.98EP3*4E5SHA7I96Q70UF74SPSIJI.BUHQJ$:K$9M51H9Z6RPHR.K-XT855UJJZC8C*MSITGMRE%O+:JQXV$LS7SJ1:DE LCX7RP7T JH4RR-NK.PASIWKA8J5Z1NA*BE7KFTJXO4BM5QVF.S0-5CG8KQWB8RCA1VP*1Q.ELZ1Q21G.JEGLOFH1:FR09$SCY/OGBU1QIE/2 9SK3" // Remove HC1 header if any From dfdb380223e685ff2d26683a5ca556086843bde7 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Sat, 17 Apr 2021 01:20:19 +0200 Subject: [PATCH 24/89] Rename method. --- PatientScannerDemo/COSE.swift | 2 +- PatientScannerDemo/X509.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PatientScannerDemo/COSE.swift b/PatientScannerDemo/COSE.swift index 5977616..daa65cd 100644 --- a/PatientScannerDemo/COSE.swift +++ b/PatientScannerDemo/COSE.swift @@ -74,7 +74,7 @@ struct COSE { ) let d = Data(signedPayload) let s = Data(signature) - guard let key = X509.rsa(from: rsa) else { + guard let key = X509.pubKey(from: rsa) else { return false } return Signature.verify(s, for: d, with: key) diff --git a/PatientScannerDemo/X509.swift b/PatientScannerDemo/X509.swift index a8c37e0..57af78a 100644 --- a/PatientScannerDemo/X509.swift +++ b/PatientScannerDemo/X509.swift @@ -8,9 +8,9 @@ import Foundation struct X509 { - public static func rsa(from encodedCert: String) -> SecKey? { + public static func pubKey(from b64EncodedCert: String) -> SecKey? { guard - let encodedCertData = Data(base64Encoded: encodedCert), + let encodedCertData = Data(base64Encoded: b64EncodedCert), let cert = SecCertificateCreateWithData(nil, encodedCertData as CFData), let publicKey = SecCertificateCopyKey(cert) else { From 343dc7380078dc264d10f6dea70c39496948c6e7 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Sat, 17 Apr 2021 01:23:25 +0200 Subject: [PATCH 25/89] Streamline signature service. --- PatientScannerDemo/Signature.swift | 41 ++++++++---------------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/PatientScannerDemo/Signature.swift b/PatientScannerDemo/Signature.swift index 467decb..d325818 100644 --- a/PatientScannerDemo/Signature.swift +++ b/PatientScannerDemo/Signature.swift @@ -11,43 +11,24 @@ import Foundation struct Signature { public static func verify(_ signature: Data, for data: Data, with publicKey: SecKey) -> Bool { - if SecKeyIsAlgorithmSupported(publicKey, .verify, .ecdsaSignatureMessageX962SHA256) { - return verifyEC(signature, for: data, with: publicKey) - } - if SecKeyIsAlgorithmSupported(publicKey, .verify, .rsaSignatureMessagePSSSHA256) { - return verifyRSA(signature, for: data, with: publicKey) - } - return false - } - - static func verifyEC(_ signature: Data, for data: Data, with publicKey: SecKey) -> Bool { - let sig = ASN1.signature(from: signature) + var signature = signature + var alg: SecKeyAlgorithm - var error: Unmanaged? - let result = SecKeyVerifySignature( - publicKey, - .ecdsaSignatureMessageX962SHA256, - data as NSData, - sig as NSData, - &error - ) - if let err = error?.takeUnretainedValue().localizedDescription { - print(err) + if SecKeyIsAlgorithmSupported(publicKey, .verify, .ecdsaSignatureMessageX962SHA256) { + alg = .ecdsaSignatureMessageX962SHA256 + signature = ASN1.signature(from: signature) + } else if SecKeyIsAlgorithmSupported(publicKey, .verify, .rsaSignatureMessagePSSSHA256) { + alg = .rsaSignatureMessagePSSSHA256 + } else { + return false } - error?.release() - - return result - } - - static func verifyRSA(_ signature: Data, for data: Data, with publicKey: SecKey) -> Bool { - let sig = signature var error: Unmanaged? let result = SecKeyVerifySignature( publicKey, - .rsaSignatureMessagePSSSHA256, + alg, data as NSData, - sig as NSData, + signature as NSData, &error ) if let err = error?.takeUnretainedValue().localizedDescription { From be593802f4af1d3df11f90153571c00b924ee6dd Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Sat, 17 Apr 2021 01:27:07 +0200 Subject: [PATCH 26/89] Streamline tests. --- PatientScannerDemoTests/EHNTests.swift | 52 ++++---------------------- 1 file changed, 7 insertions(+), 45 deletions(-) diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index 1de7cd4..374534d 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -74,53 +74,15 @@ class EHNTests: XCTestCase { XCTAssert(false) } func testCoseEcAT() throws { - var barcode = "HC1NCFI.L3B6AP2YQ2%MNBCHC51/CAOZDL+OL7S99U60SVOGSHD%24R4PCTH7Y9KL6EVJBIMBL364D X1KKLZ*I9K4RLDR7B011EROZS6022WR5VX4QG9W72HWCC12B:TWZG.%N8GWBCOV0O%5F9U7H 8P4L.%2/:6TXB/-J6ZJ.*QYIBYSD6/T.6RDMMK0PX6HTPO1REO*CWMFG5CJ38+FBS+8DB9*2FFP9Z8HEM137CRBQ.893$I.R7 DRFOVMUQRVDP4IU613/G-0LZ:43+MM:QO.CQPJU21-7PJ*L/*DVLO:Q5G-7%WF4ZO*JJR:KH+O1707M6.73VXG0+0050+IMIFH:3V+DL3JK/21/LEI$T5TUT8P:40P10AXGBRS%-GZS8TGF-IT3-HU2SVJUAVG%AGO98R00Y.QT23DVP0TB*-J6YJP 8TU9U/OJSQGGMK+K3MH IR U7H%9/UU07AGEWMVTOBAYIV4SPGC2Y5FJJ67I4/J4FXM3GP:SAOZQJPL%WGP4BT59Q8K5MB*M44%K9JTWB9K+LS-2I9ST+3J%0X%1YGN0E0KL3/FHTZHEF9WIC4Q1HVK74L186BWT9+TJR7C2M%9JXN8S%0PVU8GFBET%0PG RR1KD2F11G-CW8A4124N9VN-T-:292AX*B%ER*$12-O:6K:/N$ 7IYFFXQ/5F NC49M/W5501B2OKU7E:NHMM8SETWUK*I$JR" - - // Remove HC1 header if any - if (barcode.hasPrefix("HC1")) { - barcode = String(barcode.suffix(barcode.count-3)) - } - - guard - let compressed = try? barcode.fromBase45() - else { - XCTAssert(false) - return - } - - let data = decompress(compressed) - - guard - let kidBytes = CBOR.kid(from: data), - let kid = String(data: Data(kidBytes), encoding: .utf8), - let url = URL(string: "https://dev.a-sit.at/certservice/cert/\(kid)") - else { - XCTAssert(false) - return - } - let expectation = XCTestExpectation(description: "Download PubKey") - URLSession.shared.dataTask(with: URLRequest(url: url)) { body, response, error in - guard - error == nil, - let status = (response as? HTTPURLResponse)?.statusCode, - 200 == status, - let body = body - else { - XCTAssert(false) - return - } - let encodedCert = body.base64EncodedString() - if COSE.verify(data, with: encodedCert) { - expectation.fulfill() - } else { - XCTAssert(false) - } - }.resume() - wait(for: [expectation], timeout: 15) + let barcode = "HC1NCFI.L3B6AP2YQ2%MNBCHC51/CAOZDL+OL7S99U60SVOGSHD%24R4PCTH7Y9KL6EVJBIMBL364D X1KKLZ*I9K4RLDR7B011EROZS6022WR5VX4QG9W72HWCC12B:TWZG.%N8GWBCOV0O%5F9U7H 8P4L.%2/:6TXB/-J6ZJ.*QYIBYSD6/T.6RDMMK0PX6HTPO1REO*CWMFG5CJ38+FBS+8DB9*2FFP9Z8HEM137CRBQ.893$I.R7 DRFOVMUQRVDP4IU613/G-0LZ:43+MM:QO.CQPJU21-7PJ*L/*DVLO:Q5G-7%WF4ZO*JJR:KH+O1707M6.73VXG0+0050+IMIFH:3V+DL3JK/21/LEI$T5TUT8P:40P10AXGBRS%-GZS8TGF-IT3-HU2SVJUAVG%AGO98R00Y.QT23DVP0TB*-J6YJP 8TU9U/OJSQGGMK+K3MH IR U7H%9/UU07AGEWMVTOBAYIV4SPGC2Y5FJJ67I4/J4FXM3GP:SAOZQJPL%WGP4BT59Q8K5MB*M44%K9JTWB9K+LS-2I9ST+3J%0X%1YGN0E0KL3/FHTZHEF9WIC4Q1HVK74L186BWT9+TJR7C2M%9JXN8S%0PVU8GFBET%0PG RR1KD2F11G-CW8A4124N9VN-T-:292AX*B%ER*$12-O:6K:/N$ 7IYFFXQ/5F NC49M/W5501B2OKU7E:NHMM8SETWUK*I$JR" + return baseTestAT(barcode: barcode) } func testCoseRsaAT() throws { - var barcode = "HC1NCFI.LUZB.P2YQ2E R002$DLTLIYXM/+0JNEAFUP.CV5GKCL /A0SQT/O8ZA85D0IJ$5D4.J+MR8-EGK6DM1R58V1ERUCWM4.E4ZM4$WG O E6KX9$KHCQMFE0B$KPKA*A2+ELQ*5ZQE/*1ZMSM5S.:KGQ33LQOWN67QW68LXM867D6837QCWEU*E*OKZCJPSCPIM1:Q83FBODLRD/W8K$E4 SG4P2JM6GCMU9FFSZAKNJH6ZNZVSWU78MHB4TO5J0N51U2F:17AB8O0*N0CQSA-9VIN904*STT$6R1LLXDT8J1ZN4I4368L02N72ZMGV496.0NO3OQCPFVF+C$BKQH1$+8L:AAEGRIB548B68D/3-ZTZ.JNM84E0F59$N6DY2*6FACA448900U42ZEMMO7-LO.45*IMXYIODF:82RN4L8Q%20HDJ-YCHIA1YT87A2/C1NO1F6DPCLCK9+BDXEEK23JH0/I8XJQEQ1T8BQ5GNDRFPQKKV6WT$A+98TIOUSAFA0J8OMY87$P-LESPS1KO+:O%HOY*C8XH4ZE7D16QR WNN$EP:U7E2HTLS023X0GJBW887LCKVHDGJ+Q88I0A73$H6R30XYH-LDC$4+24*JSE*H98A471BJ3:R0LU3MZA+ 4/GMZ9J D4E7L.TI$L8L:TN4G2S552748V$%D0CPH9RJ-7Z4AXFN*SS/ZC44O3P5%%AE936OUSR1H7WP%CP8KQUCY9I%A5FDBV+0A%HPVP5SKP9TKAFKT9FYROAABDBEHVQ9317O0D7MS5Z.Q2+K2.1RGGS3B5OTO2ROD60Z6LE98E94TV09JXM395VA0N.98EP3*4E5SHA7I96Q70UF74SPSIJI.BUHQJ$:K$9M51H9Z6RPHR.K-XT855UJJZC8C*MSITGMRE%O+:JQXV$LS7SJ1:DE LCX7RP7T JH4RR-NK.PASIWKA8J5Z1NA*BE7KFTJXO4BM5QVF.S0-5CG8KQWB8RCA1VP*1Q.ELZ1Q21G.JEGLOFH1:FR09$SCY/OGBU1QIE/2 9SK3" - + let barcode = "HC1NCFI.LUZB.P2YQ2E R002$DLTLIYXM/+0JNEAFUP.CV5GKCL /A0SQT/O8ZA85D0IJ$5D4.J+MR8-EGK6DM1R58V1ERUCWM4.E4ZM4$WG O E6KX9$KHCQMFE0B$KPKA*A2+ELQ*5ZQE/*1ZMSM5S.:KGQ33LQOWN67QW68LXM867D6837QCWEU*E*OKZCJPSCPIM1:Q83FBODLRD/W8K$E4 SG4P2JM6GCMU9FFSZAKNJH6ZNZVSWU78MHB4TO5J0N51U2F:17AB8O0*N0CQSA-9VIN904*STT$6R1LLXDT8J1ZN4I4368L02N72ZMGV496.0NO3OQCPFVF+C$BKQH1$+8L:AAEGRIB548B68D/3-ZTZ.JNM84E0F59$N6DY2*6FACA448900U42ZEMMO7-LO.45*IMXYIODF:82RN4L8Q%20HDJ-YCHIA1YT87A2/C1NO1F6DPCLCK9+BDXEEK23JH0/I8XJQEQ1T8BQ5GNDRFPQKKV6WT$A+98TIOUSAFA0J8OMY87$P-LESPS1KO+:O%HOY*C8XH4ZE7D16QR WNN$EP:U7E2HTLS023X0GJBW887LCKVHDGJ+Q88I0A73$H6R30XYH-LDC$4+24*JSE*H98A471BJ3:R0LU3MZA+ 4/GMZ9J D4E7L.TI$L8L:TN4G2S552748V$%D0CPH9RJ-7Z4AXFN*SS/ZC44O3P5%%AE936OUSR1H7WP%CP8KQUCY9I%A5FDBV+0A%HPVP5SKP9TKAFKT9FYROAABDBEHVQ9317O0D7MS5Z.Q2+K2.1RGGS3B5OTO2ROD60Z6LE98E94TV09JXM395VA0N.98EP3*4E5SHA7I96Q70UF74SPSIJI.BUHQJ$:K$9M51H9Z6RPHR.K-XT855UJJZC8C*MSITGMRE%O+:JQXV$LS7SJ1:DE LCX7RP7T JH4RR-NK.PASIWKA8J5Z1NA*BE7KFTJXO4BM5QVF.S0-5CG8KQWB8RCA1VP*1Q.ELZ1Q21G.JEGLOFH1:FR09$SCY/OGBU1QIE/2 9SK3" + return baseTestAT(barcode: barcode) + } + func baseTestAT(barcode: String) { + var barcode = barcode // Remove HC1 header if any if (barcode.hasPrefix("HC1")) { barcode = String(barcode.suffix(barcode.count-3)) From 0f7decf2c382d9b3d76f65d9463c1c0d5d806085 Mon Sep 17 00:00:00 2001 From: Dirk-Willem van Gulik Date: Mon, 19 Apr 2021 09:08:13 +0200 Subject: [PATCH 27/89] Upgrade for v0.0.4 --- PatientScannerDemo/ViewController.swift | 4 ++-- PatientScannerDemoTests/EHNTests.swift | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/PatientScannerDemo/ViewController.swift b/PatientScannerDemo/ViewController.swift index 8d99795..b987a5f 100644 --- a/PatientScannerDemo/ViewController.swift +++ b/PatientScannerDemo/ViewController.swift @@ -128,10 +128,10 @@ extension ViewController { } func observationHandler(payloadS: String?) { - let payloadS: String? = "HC1NCFOXNEG2NBJ5*H:QO-.O /MD064 PJ26UV0 XHLQ9HXKZNEQCSJ591MVBATW$4 S8$96NF6OR5UVBJUB4PJU47326/Z7PCL394Z/MWP4 N66ED6JC:JEG.CZJC0:C6JK:JM$JLAINN6BLHM035L8CCECS.CYMCPOJ5OI9YI:8DRFC%PD*ZLJ9CWVBREJFZM4A7Z/M*+Q.28+VQXCRAHAF27I9QQ60E2KYIJPOJI7J/VJ0 JYSJEZIK7B*IJS7BCLIOCISEBTKBRHSWKJ4:2POJ.GILYJ7GPSVBY4CJZIOMI$MI1VC3TCYR6HCRF46Q96W/6-DP+%PPMC1KJG%HJ*81.7 84-W6I RO5PH6UDUH+/F9PJCQFRVV 8UDJ5QEV2Y8%635OHH0E2:E5VUJZ4 VT3+6ZU598O:E0/ 0VP2IBO6ANG%6UD5RSRO4B6$ES40H/CQ1" + let payloadS: String? = "HC1:NCFOXNEG2NBJ5*H:QO-.O /MD064 PJ26UV0 XHLQ9HXKZNEQCSJ591MVBATW$4 S8$96NF6OR5UVBJUB4PJU47326/Z7PCL394Z/MWP4 N66ED6JC:JEG.CZJC0:C6JK:JM$JLAINN6BLHM035L8CCECS.CYMCPOJ5OI9YI:8DRFC%PD*ZLJ9CWVBREJFZM4A7Z/M*+Q.28+VQXCRAHAF27I9QQ60E2KYIJPOJI7J/VJ0 JYSJEZIK7B*IJS7BCLIOCISEBTKBRHSWKJ4:2POJ.GILYJ7GPSVBY4CJZIOMI$MI1VC3TCYR6HCRF46Q96W/6-DP+%PPMC1KJG%HJ*81.7 84-W6I RO5PH6UDUH+/F9PJCQFRVV 8UDJ5QEV2Y8%635OHH0E2:E5VUJZ4 VT3+6ZU598O:E0/ 0VP2IBO6ANG%6UD5RSRO4B6$ES40H/CQ1" guard let payloadString = payloadS, - let compressed = try? String(payloadString.dropFirst(3)).fromBase45() + let compressed = try? String(payloadString.dropFirst(4)).fromBase45() else { return } let data = decompress(compressed) diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index 374534d..b3e3b67 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -11,7 +11,7 @@ import XCTest class EHNTests: XCTestCase { func testCoseEcdsa() throws { - var barcode = "HC1NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5" + var barcode = "HC1:NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5" let trustJson = """ [ @@ -32,9 +32,13 @@ class EHNTests: XCTestCase { ] """ - // Remove HC1 header if any + // Remove HC1 header if any (v0.0.3 'HC1', v0.0.4 'HC1:' + // if (barcode.hasPrefix("HC1")) { barcode = String(barcode.suffix(barcode.count-3)) + if (barcode.hasPrefix("1")) { + barcode = String(barcode.suffix(barcode.count-1)) + } } guard From f676cdab973f94e030959f06c211b5dad9f8f431 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Mon, 19 Apr 2021 16:28:45 +0200 Subject: [PATCH 28/89] Lower Version Requirement to 12.1 12.0 isn't available, and everything below isn't supported due to https://developer.apple.com/documentation/security/2963103-seccertificatecopykey --- PatientScannerDemo.xcodeproj/project.pbxproj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 7f197b0..4607ca8 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -418,7 +418,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.4; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -473,7 +473,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.4; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; @@ -491,6 +491,7 @@ CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; INFOPLIST_FILE = PatientScannerDemo/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -510,6 +511,7 @@ CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; INFOPLIST_FILE = PatientScannerDemo/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", From 97a07eb6ad467ed4c330aba664fc2b6f3a830069 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Mon, 19 Apr 2021 16:33:31 +0200 Subject: [PATCH 29/89] Add Floating Panel. --- PatientScannerDemo.xcodeproj/project.pbxproj | 17 +++++++++++++++++ .../xcshareddata/swiftpm/Package.resolved | 9 +++++++++ 2 files changed, 26 insertions(+) diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 4607ca8..87728e3 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + CE13CF00262DCC180070C80E /* FloatingPanel in Frameworks */ = {isa = PBXBuildFile; productRef = CE13CEFF262DCC180070C80E /* FloatingPanel */; }; CE1BDF99262A4CD600766F97 /* X509.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1BDF98262A4CD600766F97 /* X509.swift */; }; CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC93B2628A7820079FB78 /* ASN1.swift */; }; CE3CC9442628C2130079FB78 /* CBOR.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC9432628C2130079FB78 /* CBOR.swift */; }; @@ -80,6 +81,7 @@ buildActionMask = 2147483647; files = ( CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */, + CE13CF00262DCC180070C80E /* FloatingPanel in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -181,6 +183,7 @@ name = PatientScannerDemo; packageProductDependencies = ( CE7DE7F92625EF18007E6694 /* SwiftCBOR */, + CE13CEFF262DCC180070C80E /* FloatingPanel */, ); productName = PatientScannerDemo; productReference = CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */; @@ -255,6 +258,7 @@ mainGroup = CEA6D6DF261F8D2700715333; packageReferences = ( CE7DE7F82625EF18007E6694 /* XCRemoteSwiftPackageReference "SwiftCBOR" */, + CE13CEFE262DCC180070C80E /* XCRemoteSwiftPackageReference "FloatingPanel" */, ); productRefGroup = CEA6D6E9261F8D2700715333 /* Products */; projectDirPath = ""; @@ -649,6 +653,14 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + CE13CEFE262DCC180070C80E /* XCRemoteSwiftPackageReference "FloatingPanel" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SCENEE/FloatingPanel"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.3.0; + }; + }; CE7DE7F82625EF18007E6694 /* XCRemoteSwiftPackageReference "SwiftCBOR" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/unrelentingtech/SwiftCBOR"; @@ -660,6 +672,11 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + CE13CEFF262DCC180070C80E /* FloatingPanel */ = { + isa = XCSwiftPackageProductDependency; + package = CE13CEFE262DCC180070C80E /* XCRemoteSwiftPackageReference "FloatingPanel" */; + productName = FloatingPanel; + }; CE7DE7F92625EF18007E6694 /* SwiftCBOR */ = { isa = XCSwiftPackageProductDependency; package = CE7DE7F82625EF18007E6694 /* XCRemoteSwiftPackageReference "SwiftCBOR" */; diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index bc6ed56..388441f 100644 --- a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,15 @@ { "object": { "pins": [ + { + "package": "FloatingPanel", + "repositoryURL": "https://github.com/SCENEE/FloatingPanel", + "state": { + "branch": null, + "revision": "16fea625be25d9a713630a4a43cbc0778740ebf4", + "version": "2.3.0" + } + }, { "package": "SwiftCBOR", "repositoryURL": "https://github.com/unrelentingtech/SwiftCBOR", From 40a7ab376fdfd45bbb5ebccc3421fbed732963c8 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Mon, 19 Apr 2021 22:40:24 +0200 Subject: [PATCH 30/89] Restructure Project; Add CBOR methods; Add new screen. --- PatientScannerDemo.xcodeproj/project.pbxproj | 116 +++++++++++++---- .../Components/FullFloatingPanelLayout.swift | 21 +++ .../Components/RoundedButton.swift | 32 +++++ .../{ => Extensions}/Data+hexString.swift | 0 PatientScannerDemo/Extensions/Date.swift | 30 +++++ .../{ => Extensions}/String+JSON.swift | 0 PatientScannerDemo/{ => Services}/ASN1.swift | 0 .../{ => Services}/Base45.swift | 0 PatientScannerDemo/{ => Services}/CBOR.swift | 69 ++++++++-- PatientScannerDemo/{ => Services}/COSE.swift | 0 PatientScannerDemo/{ => Services}/JWK.swift | 0 .../{ => Services}/Signature.swift | 0 PatientScannerDemo/{ => Services}/X509.swift | 0 PatientScannerDemo/{ => Services}/ZLib.swift | 0 .../Base.lproj/LaunchScreen.storyboard | 0 .../Base.lproj/Main.storyboard | 14 +- .../Storyboards/CertificateViewer.storyboard | 121 ++++++++++++++++++ .../{ => SupportingFiles}/AppDelegate.swift | 0 .../AccentColor.colorset/Contents.json | 0 .../AppIcon.appiconset/Contents.json | 0 .../Assets.xcassets/Contents.json | 0 .../{ => SupportingFiles}/Info.plist | 0 .../{ => SupportingFiles}/SceneDelegate.swift | 0 .../ViewControllers/CertificateViewer.swift | 42 ++++++ .../Scan.swift} | 44 +++++-- 25 files changed, 437 insertions(+), 52 deletions(-) create mode 100644 PatientScannerDemo/Components/FullFloatingPanelLayout.swift create mode 100644 PatientScannerDemo/Components/RoundedButton.swift rename PatientScannerDemo/{ => Extensions}/Data+hexString.swift (100%) create mode 100644 PatientScannerDemo/Extensions/Date.swift rename PatientScannerDemo/{ => Extensions}/String+JSON.swift (100%) rename PatientScannerDemo/{ => Services}/ASN1.swift (100%) rename PatientScannerDemo/{ => Services}/Base45.swift (100%) rename PatientScannerDemo/{ => Services}/CBOR.swift (50%) rename PatientScannerDemo/{ => Services}/COSE.swift (100%) rename PatientScannerDemo/{ => Services}/JWK.swift (100%) rename PatientScannerDemo/{ => Services}/Signature.swift (100%) rename PatientScannerDemo/{ => Services}/X509.swift (100%) rename PatientScannerDemo/{ => Services}/ZLib.swift (100%) rename PatientScannerDemo/{ => Storyboards}/Base.lproj/LaunchScreen.storyboard (100%) rename PatientScannerDemo/{ => Storyboards}/Base.lproj/Main.storyboard (61%) create mode 100644 PatientScannerDemo/Storyboards/CertificateViewer.storyboard rename PatientScannerDemo/{ => SupportingFiles}/AppDelegate.swift (100%) rename PatientScannerDemo/{ => SupportingFiles}/Assets.xcassets/AccentColor.colorset/Contents.json (100%) rename PatientScannerDemo/{ => SupportingFiles}/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename PatientScannerDemo/{ => SupportingFiles}/Assets.xcassets/Contents.json (100%) rename PatientScannerDemo/{ => SupportingFiles}/Info.plist (100%) rename PatientScannerDemo/{ => SupportingFiles}/SceneDelegate.swift (100%) create mode 100644 PatientScannerDemo/ViewControllers/CertificateViewer.swift rename PatientScannerDemo/{ViewController.swift => ViewControllers/Scan.swift} (83%) diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 87728e3..5bd298f 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -8,13 +8,18 @@ /* Begin PBXBuildFile section */ CE13CF00262DCC180070C80E /* FloatingPanel in Frameworks */ = {isa = PBXBuildFile; productRef = CE13CEFF262DCC180070C80E /* FloatingPanel */; }; + CE13CF05262DCDCD0070C80E /* CertificateViewer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE13CF04262DCDCD0070C80E /* CertificateViewer.storyboard */; }; + CE13CF0A262DCDDA0070C80E /* CertificateViewer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE13CF09262DCDDA0070C80E /* CertificateViewer.swift */; }; + CE13CF0F262DD0D80070C80E /* FullFloatingPanelLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE13CF0E262DD0D80070C80E /* FullFloatingPanelLayout.swift */; }; + CE13CF23262DDF810070C80E /* RoundedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE13CF22262DDF810070C80E /* RoundedButton.swift */; }; + CE157F81262E1F7A00FE4821 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE157F80262E1F7A00FE4821 /* Date.swift */; }; CE1BDF99262A4CD600766F97 /* X509.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1BDF98262A4CD600766F97 /* X509.swift */; }; CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC93B2628A7820079FB78 /* ASN1.swift */; }; CE3CC9442628C2130079FB78 /* CBOR.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC9432628C2130079FB78 /* CBOR.swift */; }; CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CE7DE7F92625EF18007E6694 /* SwiftCBOR */; }; CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EB261F8D2700715333 /* AppDelegate.swift */; }; CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */; }; - CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EF261F8D2700715333 /* ViewController.swift */; }; + CEA6D6F0261F8D2700715333 /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EF261F8D2700715333 /* Scan.swift */; }; CEA6D6F3261F8D2700715333 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F1261F8D2700715333 /* Main.storyboard */; }; CEA6D6F5261F8D2900715333 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F4261F8D2900715333 /* Assets.xcassets */; }; CEA6D6F8261F8D2900715333 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */; }; @@ -48,13 +53,18 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + CE13CF04262DCDCD0070C80E /* CertificateViewer.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = CertificateViewer.storyboard; sourceTree = ""; }; + CE13CF09262DCDDA0070C80E /* CertificateViewer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CertificateViewer.swift; sourceTree = ""; }; + CE13CF0E262DD0D80070C80E /* FullFloatingPanelLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullFloatingPanelLayout.swift; sourceTree = ""; }; + CE13CF22262DDF810070C80E /* RoundedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedButton.swift; sourceTree = ""; }; + CE157F80262E1F7A00FE4821 /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = ""; }; CE1BDF98262A4CD600766F97 /* X509.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = X509.swift; sourceTree = ""; }; CE3CC93B2628A7820079FB78 /* ASN1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASN1.swift; sourceTree = ""; }; CE3CC9432628C2130079FB78 /* CBOR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBOR.swift; sourceTree = ""; }; CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PatientScannerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; CEA6D6EB261F8D2700715333 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - CEA6D6EF261F8D2700715333 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + CEA6D6EF261F8D2700715333 /* Scan.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scan.swift; sourceTree = ""; }; CEA6D6F2261F8D2700715333 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; CEA6D6F4261F8D2900715333 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; CEA6D6F7261F8D2900715333 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; @@ -102,6 +112,70 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + CE13CF19262DDE200070C80E /* Storyboards */ = { + isa = PBXGroup; + children = ( + CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */, + CEA6D6F1261F8D2700715333 /* Main.storyboard */, + CE13CF04262DCDCD0070C80E /* CertificateViewer.storyboard */, + ); + path = Storyboards; + sourceTree = ""; + }; + CE13CF1A262DDE330070C80E /* Services */ = { + isa = PBXGroup; + children = ( + CEC2C4C02625ED030056E406 /* JWK.swift */, + CEC2C4BF2625ED030056E406 /* ZLib.swift */, + CEC2C4C12625ED030056E406 /* Base45.swift */, + CEFAD86C2625F164009AFEF9 /* Signature.swift */, + CE3CC93B2628A7820079FB78 /* ASN1.swift */, + CEFAD87926271414009AFEF9 /* COSE.swift */, + CE3CC9432628C2130079FB78 /* CBOR.swift */, + CE1BDF98262A4CD600766F97 /* X509.swift */, + ); + path = Services; + sourceTree = ""; + }; + CE13CF1B262DDE540070C80E /* Extensions */ = { + isa = PBXGroup; + children = ( + CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */, + CEFAD8712625F29E009AFEF9 /* String+JSON.swift */, + CE157F80262E1F7A00FE4821 /* Date.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + CE13CF1C262DDE600070C80E /* ViewControllers */ = { + isa = PBXGroup; + children = ( + CE13CF09262DCDDA0070C80E /* CertificateViewer.swift */, + CEA6D6EF261F8D2700715333 /* Scan.swift */, + ); + path = ViewControllers; + sourceTree = ""; + }; + CE13CF1D262DDE730070C80E /* Components */ = { + isa = PBXGroup; + children = ( + CE13CF0E262DD0D80070C80E /* FullFloatingPanelLayout.swift */, + CE13CF22262DDF810070C80E /* RoundedButton.swift */, + ); + path = Components; + sourceTree = ""; + }; + CE13CF1E262DDE800070C80E /* SupportingFiles */ = { + isa = PBXGroup; + children = ( + CEA6D6EB261F8D2700715333 /* AppDelegate.swift */, + CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */, + CEA6D6F4261F8D2900715333 /* Assets.xcassets */, + CEA6D6F9261F8D2900715333 /* Info.plist */, + ); + path = SupportingFiles; + sourceTree = ""; + }; CEA6D6DF261F8D2700715333 = { isa = PBXGroup; children = ( @@ -125,23 +199,12 @@ CEA6D6EA261F8D2700715333 /* PatientScannerDemo */ = { isa = PBXGroup; children = ( - CEFAD8712625F29E009AFEF9 /* String+JSON.swift */, - CEC2C4C12625ED030056E406 /* Base45.swift */, - CEC2C4C02625ED030056E406 /* JWK.swift */, - CEC2C4BF2625ED030056E406 /* ZLib.swift */, - CEA6D6EB261F8D2700715333 /* AppDelegate.swift */, - CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */, - CEA6D6EF261F8D2700715333 /* ViewController.swift */, - CEA6D6F1261F8D2700715333 /* Main.storyboard */, - CEA6D6F4261F8D2900715333 /* Assets.xcassets */, - CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */, - CEA6D6F9261F8D2900715333 /* Info.plist */, - CEFAD86C2625F164009AFEF9 /* Signature.swift */, - CE3CC93B2628A7820079FB78 /* ASN1.swift */, - CEFAD87926271414009AFEF9 /* COSE.swift */, - CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */, - CE3CC9432628C2130079FB78 /* CBOR.swift */, - CE1BDF98262A4CD600766F97 /* X509.swift */, + CE13CF1E262DDE800070C80E /* SupportingFiles */, + CE13CF1D262DDE730070C80E /* Components */, + CE13CF1C262DDE600070C80E /* ViewControllers */, + CE13CF1B262DDE540070C80E /* Extensions */, + CE13CF1A262DDE330070C80E /* Services */, + CE13CF19262DDE200070C80E /* Storyboards */, ); path = PatientScannerDemo; sourceTree = ""; @@ -276,6 +339,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + CE13CF05262DCDCD0070C80E /* CertificateViewer.storyboard in Resources */, CEA6D6F8261F8D2900715333 /* LaunchScreen.storyboard in Resources */, CEA6D6F5261F8D2900715333 /* Assets.xcassets in Resources */, CEA6D6F3261F8D2700715333 /* Main.storyboard in Resources */, @@ -304,14 +368,18 @@ buildActionMask = 2147483647; files = ( CEFAD88726271B9A009AFEF9 /* Data+hexString.swift in Sources */, + CE13CF0A262DCDDA0070C80E /* CertificateViewer.swift in Sources */, CEC2C4C32625ED030056E406 /* JWK.swift in Sources */, CEC2C4C42625ED030056E406 /* Base45.swift in Sources */, CE3CC9442628C2130079FB78 /* CBOR.swift in Sources */, + CE13CF0F262DD0D80070C80E /* FullFloatingPanelLayout.swift in Sources */, + CE157F81262E1F7A00FE4821 /* Date.swift in Sources */, CE1BDF99262A4CD600766F97 /* X509.swift in Sources */, - CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */, + CEA6D6F0261F8D2700715333 /* Scan.swift in Sources */, CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */, CEFAD87A26271414009AFEF9 /* COSE.swift in Sources */, CEFAD86D2625F164009AFEF9 /* Signature.swift in Sources */, + CE13CF23262DDF810070C80E /* RoundedButton.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, CEFAD8722625F29E009AFEF9 /* String+JSON.swift in Sources */, CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */, @@ -494,7 +562,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemo/Info.plist; + INFOPLIST_FILE = PatientScannerDemo/SupportingFiles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -514,7 +582,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemo/Info.plist; + INFOPLIST_FILE = PatientScannerDemo/SupportingFiles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -534,7 +602,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemoTests/Info.plist; + INFOPLIST_FILE = PatientScannerDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -556,7 +624,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemoTests/Info.plist; + INFOPLIST_FILE = PatientScannerDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/PatientScannerDemo/Components/FullFloatingPanelLayout.swift b/PatientScannerDemo/Components/FullFloatingPanelLayout.swift new file mode 100644 index 0000000..a599406 --- /dev/null +++ b/PatientScannerDemo/Components/FullFloatingPanelLayout.swift @@ -0,0 +1,21 @@ +// +// FullFloatingPanelLayout.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/19/21. +// + +import FloatingPanel + +class FullFloatingPanelLayout: FloatingPanelLayout { + var position: FloatingPanelPosition = .bottom + + var initialState: FloatingPanelState = .full + + var anchors: [FloatingPanelState: FloatingPanelLayoutAnchoring] { + let top = FloatingPanelLayoutAnchor(absoluteInset: 16.0, edge: .top, referenceGuide: .safeArea) + return [ + .full: top, + ] + } +} diff --git a/PatientScannerDemo/Components/RoundedButton.swift b/PatientScannerDemo/Components/RoundedButton.swift new file mode 100644 index 0000000..2afdded --- /dev/null +++ b/PatientScannerDemo/Components/RoundedButton.swift @@ -0,0 +1,32 @@ +// +// RoundedButton.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/19/21. +// + +import Foundation +import UIKit + +@IBDesignable +class RoundedButton: UIButton { + @IBInspectable var radius: CGFloat = 6.0 { didSet(v) { initialize() } } + @IBInspectable var padding: CGFloat = 4.0 { didSet(v) { initialize() } } + + override init(frame: CGRect) { + super.init(frame: frame) + + initialize() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + + initialize() + } + + func initialize() { + layer.cornerRadius = radius + contentEdgeInsets = UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding) + } +} diff --git a/PatientScannerDemo/Data+hexString.swift b/PatientScannerDemo/Extensions/Data+hexString.swift similarity index 100% rename from PatientScannerDemo/Data+hexString.swift rename to PatientScannerDemo/Extensions/Data+hexString.swift diff --git a/PatientScannerDemo/Extensions/Date.swift b/PatientScannerDemo/Extensions/Date.swift new file mode 100644 index 0000000..6751018 --- /dev/null +++ b/PatientScannerDemo/Extensions/Date.swift @@ -0,0 +1,30 @@ +// +// Date.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/19/21. +// + +import Foundation + +extension Date { + static func formatter(for locale: String, utcPosix: Bool = true, utc: Bool = false) -> DateFormatter { + let dateTimeFormatter = DateFormatter() + dateTimeFormatter.dateFormat = locale + dateTimeFormatter.timeZone = TimeZone.current + dateTimeFormatter.locale = Locale.current + if utcPosix || utc { + dateTimeFormatter.timeZone = TimeZone(secondsFromGMT: 0) + } + if utcPosix { + dateTimeFormatter.locale = Locale(identifier: "en_US_POSIX") + } + return dateTimeFormatter + } + + static let isoFormatter = formatter(for: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + + var isoString: String { + Date.isoFormatter.string(from: self) + } +} diff --git a/PatientScannerDemo/String+JSON.swift b/PatientScannerDemo/Extensions/String+JSON.swift similarity index 100% rename from PatientScannerDemo/String+JSON.swift rename to PatientScannerDemo/Extensions/String+JSON.swift diff --git a/PatientScannerDemo/ASN1.swift b/PatientScannerDemo/Services/ASN1.swift similarity index 100% rename from PatientScannerDemo/ASN1.swift rename to PatientScannerDemo/Services/ASN1.swift diff --git a/PatientScannerDemo/Base45.swift b/PatientScannerDemo/Services/Base45.swift similarity index 100% rename from PatientScannerDemo/Base45.swift rename to PatientScannerDemo/Services/Base45.swift diff --git a/PatientScannerDemo/CBOR.swift b/PatientScannerDemo/Services/CBOR.swift similarity index 50% rename from PatientScannerDemo/CBOR.swift rename to PatientScannerDemo/Services/CBOR.swift index 02ae8b2..a1df98e 100644 --- a/PatientScannerDemo/CBOR.swift +++ b/PatientScannerDemo/Services/CBOR.swift @@ -9,7 +9,7 @@ import Foundation import SwiftCBOR struct CBOR { - public static func payload(from data: Data) -> SwiftCBOR.CBOR? { + static func unwrap(data: Data) -> (SwiftCBOR.CBOR?, SwiftCBOR.CBOR?) { let COSE_TAG = UInt64(18) let decoder = SwiftCBOR.CBORDecoder(input: data.uint) @@ -18,26 +18,29 @@ struct CBOR { case let SwiftCBOR.CBOR.tagged(tag, cborElement) = cbor, tag.rawValue == COSE_TAG, // SIGN1 case let SwiftCBOR.CBOR.array(array) = cborElement, + case let SwiftCBOR.CBOR.byteString(protectedBytes) = array[0], + let protected = try? SwiftCBOR.CBOR.decode(protectedBytes), case let SwiftCBOR.CBOR.byteString(payloadBytes) = array[2], let payload = try? SwiftCBOR.CBOR.decode(payloadBytes) else { - return nil + return (nil, nil) } - return payload + return (payload, protected) + } + + public static func payload(from data: Data) -> SwiftCBOR.CBOR? { + return unwrap(data: data).0 + } + + public static func header(from data: Data) -> SwiftCBOR.CBOR? { + return unwrap(data: data).1 } public static func kid(from data: Data) -> [UInt8]? { - let COSE_TAG = UInt64(18) let COSE_PHDR_KID = SwiftCBOR.CBOR.unsignedInt(4) - let decoder = SwiftCBOR.CBORDecoder(input: data.uint) guard - let cbor = try? decoder.decodeItem(), - case let SwiftCBOR.CBOR.tagged(tag, cborElement) = cbor, - tag.rawValue == COSE_TAG, // SIGN1 - case let SwiftCBOR.CBOR.array(array) = cborElement, - case let SwiftCBOR.CBOR.byteString(protectedBytes) = array[0], - let protected = try? SwiftCBOR.CBOR.decode(protectedBytes), + let protected = unwrap(data: data).1, case let SwiftCBOR.CBOR.map(protectedMap) = protected else { return nil @@ -58,3 +61,47 @@ struct CBOR { } } } + +extension SwiftCBOR.CBOR { + func toString() -> String { + switch self { + case let .byteString(val): + return String(describing: val) + case let .unsignedInt(val): + return "\(val)" + case let .negativeInt(val): + return "-\(val)" + case let .utf8String(val): + return "\"\(val)\"" + case let .array(vals): + var s = "" + for val in vals { + s += (s.isEmpty ? "" : ", ") + val.toString() + } + return "[\(s)]" + case let .map(vals): + var s = "" + for pair in vals { + var key = pair.key.toString() + key = key.trimmingCharacters(in: ["\""]) + key = "\"\(key)\"" + s += (s.isEmpty ? "" : ", ") + "\(key): \(pair.value.toString())" + } + return "{\(s)}" + case let .boolean(val): + return String(describing: val) + case .null: + return "null" + case .undefined: + return "null" + case let .float(val): + return "\(val)" + case let .double(val): + return "\(val)" + case let .date(val): + return "\"\(val.isoString)\"" + default: + return "\"unsupported data\"" + } + } +} diff --git a/PatientScannerDemo/COSE.swift b/PatientScannerDemo/Services/COSE.swift similarity index 100% rename from PatientScannerDemo/COSE.swift rename to PatientScannerDemo/Services/COSE.swift diff --git a/PatientScannerDemo/JWK.swift b/PatientScannerDemo/Services/JWK.swift similarity index 100% rename from PatientScannerDemo/JWK.swift rename to PatientScannerDemo/Services/JWK.swift diff --git a/PatientScannerDemo/Signature.swift b/PatientScannerDemo/Services/Signature.swift similarity index 100% rename from PatientScannerDemo/Signature.swift rename to PatientScannerDemo/Services/Signature.swift diff --git a/PatientScannerDemo/X509.swift b/PatientScannerDemo/Services/X509.swift similarity index 100% rename from PatientScannerDemo/X509.swift rename to PatientScannerDemo/Services/X509.swift diff --git a/PatientScannerDemo/ZLib.swift b/PatientScannerDemo/Services/ZLib.swift similarity index 100% rename from PatientScannerDemo/ZLib.swift rename to PatientScannerDemo/Services/ZLib.swift diff --git a/PatientScannerDemo/Base.lproj/LaunchScreen.storyboard b/PatientScannerDemo/Storyboards/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from PatientScannerDemo/Base.lproj/LaunchScreen.storyboard rename to PatientScannerDemo/Storyboards/Base.lproj/LaunchScreen.storyboard diff --git a/PatientScannerDemo/Base.lproj/Main.storyboard b/PatientScannerDemo/Storyboards/Base.lproj/Main.storyboard similarity index 61% rename from PatientScannerDemo/Base.lproj/Main.storyboard rename to PatientScannerDemo/Storyboards/Base.lproj/Main.storyboard index 25a7638..0c8a017 100644 --- a/PatientScannerDemo/Base.lproj/Main.storyboard +++ b/PatientScannerDemo/Storyboards/Base.lproj/Main.storyboard @@ -1,24 +1,26 @@ - + + - + + - + - + - + - + diff --git a/PatientScannerDemo/Storyboards/CertificateViewer.storyboard b/PatientScannerDemo/Storyboards/CertificateViewer.storyboard new file mode 100644 index 0000000..df09785 --- /dev/null +++ b/PatientScannerDemo/Storyboards/CertificateViewer.storyboard @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PatientScannerDemo/AppDelegate.swift b/PatientScannerDemo/SupportingFiles/AppDelegate.swift similarity index 100% rename from PatientScannerDemo/AppDelegate.swift rename to PatientScannerDemo/SupportingFiles/AppDelegate.swift diff --git a/PatientScannerDemo/Assets.xcassets/AccentColor.colorset/Contents.json b/PatientScannerDemo/SupportingFiles/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from PatientScannerDemo/Assets.xcassets/AccentColor.colorset/Contents.json rename to PatientScannerDemo/SupportingFiles/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/PatientScannerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/PatientScannerDemo/SupportingFiles/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from PatientScannerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json rename to PatientScannerDemo/SupportingFiles/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/PatientScannerDemo/Assets.xcassets/Contents.json b/PatientScannerDemo/SupportingFiles/Assets.xcassets/Contents.json similarity index 100% rename from PatientScannerDemo/Assets.xcassets/Contents.json rename to PatientScannerDemo/SupportingFiles/Assets.xcassets/Contents.json diff --git a/PatientScannerDemo/Info.plist b/PatientScannerDemo/SupportingFiles/Info.plist similarity index 100% rename from PatientScannerDemo/Info.plist rename to PatientScannerDemo/SupportingFiles/Info.plist diff --git a/PatientScannerDemo/SceneDelegate.swift b/PatientScannerDemo/SupportingFiles/SceneDelegate.swift similarity index 100% rename from PatientScannerDemo/SceneDelegate.swift rename to PatientScannerDemo/SupportingFiles/SceneDelegate.swift diff --git a/PatientScannerDemo/ViewControllers/CertificateViewer.swift b/PatientScannerDemo/ViewControllers/CertificateViewer.swift new file mode 100644 index 0000000..71b681e --- /dev/null +++ b/PatientScannerDemo/ViewControllers/CertificateViewer.swift @@ -0,0 +1,42 @@ +// +// CertificateViewer.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/19/21. +// + +import Foundation +import UIKit +import FloatingPanel + +let DISMISS_TIMEOUT = 15.0 + +class CertificateViewerVC: UIViewController { + @IBOutlet var loadingBackground: UIView! + @IBOutlet var loadingBackgroundTrailing: NSLayoutConstraint! + + override func viewDidLoad() { + super.viewDidLoad() + + return + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + loadingBackground.layer.zPosition = -1 + loadingBackgroundTrailing.priority = .init(200) + UIView.animate(withDuration: DISMISS_TIMEOUT, delay: 0, options: .curveLinear) { [weak self] in + self?.view.layoutIfNeeded() + } + DispatchQueue.main.asyncAfter(deadline: .now() + DISMISS_TIMEOUT) { [weak self] in + self?.dismiss(animated: true, completion: nil) + } + + return + } + + @IBAction + func closeButton() { + dismiss(animated: true, completion: nil) + } +} diff --git a/PatientScannerDemo/ViewController.swift b/PatientScannerDemo/ViewControllers/Scan.swift similarity index 83% rename from PatientScannerDemo/ViewController.swift rename to PatientScannerDemo/ViewControllers/Scan.swift index 8d99795..98d362d 100644 --- a/PatientScannerDemo/ViewController.swift +++ b/PatientScannerDemo/ViewControllers/Scan.swift @@ -11,10 +11,10 @@ import UIKit import Vision import AVFoundation import SwiftCBOR -//import CryptorECC +import FloatingPanel -class ViewController: UIViewController { +class ScanVC: UIViewController { var captureSession = AVCaptureSession() lazy var detectBarcodeRequest = VNDetectBarcodesRequest { request, error in @@ -27,9 +27,11 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - checkPermissions() - setupCameraLiveView() -// observationHandler(payloadS: nil) +// checkPermissions() +// setupCameraLiveView() + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + self.observationHandler(payloadS: nil) + } } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) @@ -59,10 +61,29 @@ class ViewController: UIViewController { // } // // } + + func presentViewer(for certificate: Any?) { + let fpc = FloatingPanelController() + guard + let contentVC = UIStoryboard(name: "CertificateViewer", bundle: nil) + .instantiateInitialViewController(), + let viewer = contentVC as? CertificateViewerVC + else { + return + } + + fpc.set(contentViewController: viewer) + fpc.isRemovalInteractionEnabled = true // Let it removable by a swipe-down + fpc.layout = FullFloatingPanelLayout() + fpc.surfaceView.layer.cornerRadius = 24.0 + fpc.surfaceView.clipsToBounds = true + + present(fpc, animated: true, completion: nil) + } } -extension ViewController { +extension ScanVC { private func checkPermissions() { switch AVCaptureDevice.authorizationStatus(for: .video) { case .notDetermined: @@ -135,15 +156,16 @@ extension ViewController { else { return } let data = decompress(compressed) - - /// TODO - + let payload = CBOR.payload(from: data) + presentViewer(for: payload) + print(CBOR.payload(from: data)?.toString() ?? "") + print(CBOR.header(from: data)?.toString() ?? "") } } -extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate { +extension ScanVC: AVCaptureVideoDataOutputSampleBufferDelegate { func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return } @@ -161,7 +183,7 @@ extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate { } -extension ViewController { +extension ScanVC { private func configurePreviewLayer() { let cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) cameraPreviewLayer.videoGravity = .resizeAspectFill From 2422448ca8e2df41df20811422521ee8f4f1f96e Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Mon, 19 Apr 2021 23:20:44 +0200 Subject: [PATCH 31/89] Start HCert model. --- PatientScannerDemo.xcodeproj/project.pbxproj | 33 ++++++++++ .../xcshareddata/swiftpm/Package.resolved | 9 +++ .../xcschemes/xcschememanagement.plist | 21 +++++++ .../Extensions/SwiftCBOR.CBOR.swift | 62 +++++++++++++++++++ PatientScannerDemo/Models/HCert.swift | 21 +++++++ PatientScannerDemo/Services/CBOR.swift | 44 ------------- PatientScannerDemo/ViewControllers/Scan.swift | 11 ++-- PatientScannerDemoTests/EHNTests.swift | 17 +++-- 8 files changed, 159 insertions(+), 59 deletions(-) create mode 100644 PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift create mode 100644 PatientScannerDemo/Models/HCert.swift diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 5bd298f..0135193 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -13,6 +13,9 @@ CE13CF0F262DD0D80070C80E /* FullFloatingPanelLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE13CF0E262DD0D80070C80E /* FullFloatingPanelLayout.swift */; }; CE13CF23262DDF810070C80E /* RoundedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE13CF22262DDF810070C80E /* RoundedButton.swift */; }; CE157F81262E1F7A00FE4821 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE157F80262E1F7A00FE4821 /* Date.swift */; }; + CE157F87262E24DE00FE4821 /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = CE157F86262E24DE00FE4821 /* SwiftyJSON */; }; + CE157F8D262E24F900FE4821 /* HCert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE157F8C262E24F900FE4821 /* HCert.swift */; }; + CE157F9B262E2A9F00FE4821 /* SwiftCBOR.CBOR.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE157F9A262E2A9F00FE4821 /* SwiftCBOR.CBOR.swift */; }; CE1BDF99262A4CD600766F97 /* X509.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1BDF98262A4CD600766F97 /* X509.swift */; }; CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC93B2628A7820079FB78 /* ASN1.swift */; }; CE3CC9442628C2130079FB78 /* CBOR.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC9432628C2130079FB78 /* CBOR.swift */; }; @@ -58,6 +61,8 @@ CE13CF0E262DD0D80070C80E /* FullFloatingPanelLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullFloatingPanelLayout.swift; sourceTree = ""; }; CE13CF22262DDF810070C80E /* RoundedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedButton.swift; sourceTree = ""; }; CE157F80262E1F7A00FE4821 /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = ""; }; + CE157F8C262E24F900FE4821 /* HCert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HCert.swift; sourceTree = ""; }; + CE157F9A262E2A9F00FE4821 /* SwiftCBOR.CBOR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftCBOR.CBOR.swift; sourceTree = ""; }; CE1BDF98262A4CD600766F97 /* X509.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = X509.swift; sourceTree = ""; }; CE3CC93B2628A7820079FB78 /* ASN1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASN1.swift; sourceTree = ""; }; CE3CC9432628C2130079FB78 /* CBOR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBOR.swift; sourceTree = ""; }; @@ -90,6 +95,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + CE157F87262E24DE00FE4821 /* SwiftyJSON in Frameworks */, CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */, CE13CF00262DCC180070C80E /* FloatingPanel in Frameworks */, ); @@ -143,6 +149,7 @@ CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */, CEFAD8712625F29E009AFEF9 /* String+JSON.swift */, CE157F80262E1F7A00FE4821 /* Date.swift */, + CE157F9A262E2A9F00FE4821 /* SwiftCBOR.CBOR.swift */, ); path = Extensions; sourceTree = ""; @@ -176,6 +183,14 @@ path = SupportingFiles; sourceTree = ""; }; + CE157F8B262E24EC00FE4821 /* Models */ = { + isa = PBXGroup; + children = ( + CE157F8C262E24F900FE4821 /* HCert.swift */, + ); + path = Models; + sourceTree = ""; + }; CEA6D6DF261F8D2700715333 = { isa = PBXGroup; children = ( @@ -199,6 +214,7 @@ CEA6D6EA261F8D2700715333 /* PatientScannerDemo */ = { isa = PBXGroup; children = ( + CE157F8B262E24EC00FE4821 /* Models */, CE13CF1E262DDE800070C80E /* SupportingFiles */, CE13CF1D262DDE730070C80E /* Components */, CE13CF1C262DDE600070C80E /* ViewControllers */, @@ -247,6 +263,7 @@ packageProductDependencies = ( CE7DE7F92625EF18007E6694 /* SwiftCBOR */, CE13CEFF262DCC180070C80E /* FloatingPanel */, + CE157F86262E24DE00FE4821 /* SwiftyJSON */, ); productName = PatientScannerDemo; productReference = CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */; @@ -322,6 +339,7 @@ packageReferences = ( CE7DE7F82625EF18007E6694 /* XCRemoteSwiftPackageReference "SwiftCBOR" */, CE13CEFE262DCC180070C80E /* XCRemoteSwiftPackageReference "FloatingPanel" */, + CE157F85262E24DE00FE4821 /* XCRemoteSwiftPackageReference "SwiftyJSON" */, ); productRefGroup = CEA6D6E9261F8D2700715333 /* Products */; projectDirPath = ""; @@ -367,6 +385,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CE157F8D262E24F900FE4821 /* HCert.swift in Sources */, CEFAD88726271B9A009AFEF9 /* Data+hexString.swift in Sources */, CE13CF0A262DCDDA0070C80E /* CertificateViewer.swift in Sources */, CEC2C4C32625ED030056E406 /* JWK.swift in Sources */, @@ -384,6 +403,7 @@ CEFAD8722625F29E009AFEF9 /* String+JSON.swift in Sources */, CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */, CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */, + CE157F9B262E2A9F00FE4821 /* SwiftCBOR.CBOR.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -729,6 +749,14 @@ minimumVersion = 2.3.0; }; }; + CE157F85262E24DE00FE4821 /* XCRemoteSwiftPackageReference "SwiftyJSON" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SwiftyJSON/SwiftyJSON"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.0.1; + }; + }; CE7DE7F82625EF18007E6694 /* XCRemoteSwiftPackageReference "SwiftCBOR" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/unrelentingtech/SwiftCBOR"; @@ -745,6 +773,11 @@ package = CE13CEFE262DCC180070C80E /* XCRemoteSwiftPackageReference "FloatingPanel" */; productName = FloatingPanel; }; + CE157F86262E24DE00FE4821 /* SwiftyJSON */ = { + isa = XCSwiftPackageProductDependency; + package = CE157F85262E24DE00FE4821 /* XCRemoteSwiftPackageReference "SwiftyJSON" */; + productName = SwiftyJSON; + }; CE7DE7F92625EF18007E6694 /* SwiftCBOR */ = { isa = XCSwiftPackageProductDependency; package = CE7DE7F82625EF18007E6694 /* XCRemoteSwiftPackageReference "SwiftCBOR" */; diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 388441f..5d5cdc2 100644 --- a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -18,6 +18,15 @@ "revision": "668c26fc3373d5f1bccbaad7665ca6048797e324", "version": "0.4.3" } + }, + { + "package": "SwiftyJSON", + "repositoryURL": "https://github.com/SwiftyJSON/SwiftyJSON", + "state": { + "branch": null, + "revision": "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07", + "version": "5.0.1" + } } ] }, diff --git a/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist b/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist index 3949b55..9db6955 100644 --- a/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist @@ -9,6 +9,27 @@ orderHint 0 + Playground (Playground) 1.xcscheme + + isShown + + orderHint + 2 + + Playground (Playground) 2.xcscheme + + isShown + + orderHint + 3 + + Playground (Playground).xcscheme + + isShown + + orderHint + 0 + diff --git a/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift b/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift new file mode 100644 index 0000000..ff7eaf0 --- /dev/null +++ b/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift @@ -0,0 +1,62 @@ +// +// SwiftCBOR.CBOR.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/19/21. +// + +import Foundation +import SwiftCBOR + +extension SwiftCBOR.CBOR { + func toString() -> String { + switch self { + case let .byteString(val): + let fallBack = "[" + val.map { + "\($0)" + }.joined(separator: ", ") + "]" + if + let child = try? SwiftCBOR.CBOR.decode(val), + case .map(_) = child + { + return child.toString() + } + return fallBack + case let .unsignedInt(val): + return "\(val)" + case let .negativeInt(val): + return "-\(val)" + case let .utf8String(val): + return "\"\(val)\"" + case let .array(vals): + var s = "" + for val in vals { + s += (s.isEmpty ? "" : ", ") + val.toString() + } + return "[\(s)]" + case let .map(vals): + var s = "" + for pair in vals { + var key = pair.key.toString() + key = key.trimmingCharacters(in: ["\""]) + key = "\"\(key)\"" + s += (s.isEmpty ? "" : ", ") + "\(key): \(pair.value.toString())" + } + return "{\(s)}" + case let .boolean(val): + return String(describing: val) + case .null: + return "null" + case .undefined: + return "null" + case let .float(val): + return "\(val)" + case let .double(val): + return "\(val)" + case let .date(val): + return "\"\(val.isoString)\"" + default: + return "\"unsupported data\"" + } + } +} diff --git a/PatientScannerDemo/Models/HCert.swift b/PatientScannerDemo/Models/HCert.swift new file mode 100644 index 0000000..1558068 --- /dev/null +++ b/PatientScannerDemo/Models/HCert.swift @@ -0,0 +1,21 @@ +// +// HCert.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/19/21. +// + +import Foundation +import SwiftyJSON + +struct HCert { + init(from cborData: Data) { + let headerStr = CBOR.header(from: cborData)?.toString() ?? "{}" + let bodyStr = CBOR.payload(from: cborData)?.toString() ?? "{}" + header = JSON(parseJSON: headerStr) + body = JSON(parseJSON: bodyStr) + } + + var header: JSON + var body: JSON +} diff --git a/PatientScannerDemo/Services/CBOR.swift b/PatientScannerDemo/Services/CBOR.swift index a1df98e..3af9f8d 100644 --- a/PatientScannerDemo/Services/CBOR.swift +++ b/PatientScannerDemo/Services/CBOR.swift @@ -61,47 +61,3 @@ struct CBOR { } } } - -extension SwiftCBOR.CBOR { - func toString() -> String { - switch self { - case let .byteString(val): - return String(describing: val) - case let .unsignedInt(val): - return "\(val)" - case let .negativeInt(val): - return "-\(val)" - case let .utf8String(val): - return "\"\(val)\"" - case let .array(vals): - var s = "" - for val in vals { - s += (s.isEmpty ? "" : ", ") + val.toString() - } - return "[\(s)]" - case let .map(vals): - var s = "" - for pair in vals { - var key = pair.key.toString() - key = key.trimmingCharacters(in: ["\""]) - key = "\"\(key)\"" - s += (s.isEmpty ? "" : ", ") + "\(key): \(pair.value.toString())" - } - return "{\(s)}" - case let .boolean(val): - return String(describing: val) - case .null: - return "null" - case .undefined: - return "null" - case let .float(val): - return "\(val)" - case let .double(val): - return "\(val)" - case let .date(val): - return "\"\(val.isoString)\"" - default: - return "\"unsupported data\"" - } - } -} diff --git a/PatientScannerDemo/ViewControllers/Scan.swift b/PatientScannerDemo/ViewControllers/Scan.swift index 93d5763..3b8b23b 100644 --- a/PatientScannerDemo/ViewControllers/Scan.swift +++ b/PatientScannerDemo/ViewControllers/Scan.swift @@ -149,17 +149,18 @@ extension ScanVC { } func observationHandler(payloadS: String?) { - let payloadS: String? = "HC1:NCFOXNEG2NBJ5*H:QO-.O /MD064 PJ26UV0 XHLQ9HXKZNEQCSJ591MVBATW$4 S8$96NF6OR5UVBJUB4PJU47326/Z7PCL394Z/MWP4 N66ED6JC:JEG.CZJC0:C6JK:JM$JLAINN6BLHM035L8CCECS.CYMCPOJ5OI9YI:8DRFC%PD*ZLJ9CWVBREJFZM4A7Z/M*+Q.28+VQXCRAHAF27I9QQ60E2KYIJPOJI7J/VJ0 JYSJEZIK7B*IJS7BCLIOCISEBTKBRHSWKJ4:2POJ.GILYJ7GPSVBY4CJZIOMI$MI1VC3TCYR6HCRF46Q96W/6-DP+%PPMC1KJG%HJ*81.7 84-W6I RO5PH6UDUH+/F9PJCQFRVV 8UDJ5QEV2Y8%635OHH0E2:E5VUJZ4 VT3+6ZU598O:E0/ 0VP2IBO6ANG%6UD5RSRO4B6$ES40H/CQ1" + let payloadS: String? = "HC1:NCFI.LDVNOJ2J52O/SCFR078MG4:T7WNDXC5$OS9/NQ FD*7L$O:XJ345Y13WIRJXRE7RAYOY1UGZJR$1VAWKCI:248D1P%3CQSP7DZ554GVY55:35QOGVERIS2NBA8Y9YTKW/UD4O$02E$0N6DF:1P:MDXO6$V4:EA6GCMTH0DHJTPOEKYTGBND0GG7M76E$*LHO7:W1V.84QM-0JBQ2FAV7X9R-1:X1XLUI8QF2A1$ID$PGFT+JN*UROVD66HD8F4O03F4L25K/NT89*KMX*8RCH7HDI.BZ-OOC68PLIW2Q1U2 PWHJ$OB RJ BGO/CAA6/DP4IOADM+ZO4PSNTLI+Q EQT*6HN67WP.0W19Q620.C0W-6FJV8G34JH09B4FPTU0PWK2JSSXA410:8KUA6RNLW66/3JZADZCM/13:B6LG40+ERQCELE0R9J477G7+830JE3+NB:56URMXA2K4QP0N8AK%0ICW4*A7ZHCQM*G4B2Q$R8%H659U%D9JBVDB1J8VW7U77IDNG2TKH.5-RU5Y5 WBD-EL8NDWDT%GD$2-RLJGRTVD 8M09BK*2-1E6M9H 5RRK5KOM7PI:SLUH026C 8MOL9/J56J40RG/02481972OFQRI:SFGMM:VUYIH.ZJ+7S5+FJ35*-JE7UE4Q1JMQ%FXVF8KN$7TKUJC2D5.0NAMX53K%V7$R9+QE.NA+I1LQ" guard let payloadString = payloadS, let compressed = try? String(payloadString.dropFirst(4)).fromBase45() else { return } let data = decompress(compressed) - let payload = CBOR.payload(from: data) - presentViewer(for: payload) - print(CBOR.payload(from: data)?.toString() ?? "") - print(CBOR.header(from: data)?.toString() ?? "") +// let payload = CBOR.payload(from: data) +// presentViewer(for: payload) +// print(CBOR.payload(from: data)?.toString() ?? "") +// print(CBOR.header(from: data)?.toString() ?? "") + HCert(from: data) } } diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index b3e3b67..391a691 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -32,13 +32,10 @@ class EHNTests: XCTestCase { ] """ - // Remove HC1 header if any (v0.0.3 'HC1', v0.0.4 'HC1:' + // Remove HC1 header if any (v0.0.3 'HC1', v0.0.4 'HC1:') // - if (barcode.hasPrefix("HC1")) { - barcode = String(barcode.suffix(barcode.count-3)) - if (barcode.hasPrefix("1")) { - barcode = String(barcode.suffix(barcode.count-1)) - } + if (barcode.hasPrefix("HC1:")) { + barcode = String(barcode.suffix(barcode.count-4)) } guard @@ -78,18 +75,18 @@ class EHNTests: XCTestCase { XCTAssert(false) } func testCoseEcAT() throws { - let barcode = "HC1NCFI.L3B6AP2YQ2%MNBCHC51/CAOZDL+OL7S99U60SVOGSHD%24R4PCTH7Y9KL6EVJBIMBL364D X1KKLZ*I9K4RLDR7B011EROZS6022WR5VX4QG9W72HWCC12B:TWZG.%N8GWBCOV0O%5F9U7H 8P4L.%2/:6TXB/-J6ZJ.*QYIBYSD6/T.6RDMMK0PX6HTPO1REO*CWMFG5CJ38+FBS+8DB9*2FFP9Z8HEM137CRBQ.893$I.R7 DRFOVMUQRVDP4IU613/G-0LZ:43+MM:QO.CQPJU21-7PJ*L/*DVLO:Q5G-7%WF4ZO*JJR:KH+O1707M6.73VXG0+0050+IMIFH:3V+DL3JK/21/LEI$T5TUT8P:40P10AXGBRS%-GZS8TGF-IT3-HU2SVJUAVG%AGO98R00Y.QT23DVP0TB*-J6YJP 8TU9U/OJSQGGMK+K3MH IR U7H%9/UU07AGEWMVTOBAYIV4SPGC2Y5FJJ67I4/J4FXM3GP:SAOZQJPL%WGP4BT59Q8K5MB*M44%K9JTWB9K+LS-2I9ST+3J%0X%1YGN0E0KL3/FHTZHEF9WIC4Q1HVK74L186BWT9+TJR7C2M%9JXN8S%0PVU8GFBET%0PG RR1KD2F11G-CW8A4124N9VN-T-:292AX*B%ER*$12-O:6K:/N$ 7IYFFXQ/5F NC49M/W5501B2OKU7E:NHMM8SETWUK*I$JR" + let barcode = "HC1:NCFI.L3B6AP2YQ2%MNBCHC51/CAOZDL+OL7S99U60SVOGSHD%24R4PCTH7Y9KL6EVJBIMBL364D X1KKLZ*I9K4RLDR7B011EROZS6022WR5VX4QG9W72HWCC12B:TWZG.%N8GWBCOV0O%5F9U7H 8P4L.%2/:6TXB/-J6ZJ.*QYIBYSD6/T.6RDMMK0PX6HTPO1REO*CWMFG5CJ38+FBS+8DB9*2FFP9Z8HEM137CRBQ.893$I.R7 DRFOVMUQRVDP4IU613/G-0LZ:43+MM:QO.CQPJU21-7PJ*L/*DVLO:Q5G-7%WF4ZO*JJR:KH+O1707M6.73VXG0+0050+IMIFH:3V+DL3JK/21/LEI$T5TUT8P:40P10AXGBRS%-GZS8TGF-IT3-HU2SVJUAVG%AGO98R00Y.QT23DVP0TB*-J6YJP 8TU9U/OJSQGGMK+K3MH IR U7H%9/UU07AGEWMVTOBAYIV4SPGC2Y5FJJ67I4/J4FXM3GP:SAOZQJPL%WGP4BT59Q8K5MB*M44%K9JTWB9K+LS-2I9ST+3J%0X%1YGN0E0KL3/FHTZHEF9WIC4Q1HVK74L186BWT9+TJR7C2M%9JXN8S%0PVU8GFBET%0PG RR1KD2F11G-CW8A4124N9VN-T-:292AX*B%ER*$12-O:6K:/N$ 7IYFFXQ/5F NC49M/W5501B2OKU7E:NHMM8SETWUK*I$JR" return baseTestAT(barcode: barcode) } func testCoseRsaAT() throws { - let barcode = "HC1NCFI.LUZB.P2YQ2E R002$DLTLIYXM/+0JNEAFUP.CV5GKCL /A0SQT/O8ZA85D0IJ$5D4.J+MR8-EGK6DM1R58V1ERUCWM4.E4ZM4$WG O E6KX9$KHCQMFE0B$KPKA*A2+ELQ*5ZQE/*1ZMSM5S.:KGQ33LQOWN67QW68LXM867D6837QCWEU*E*OKZCJPSCPIM1:Q83FBODLRD/W8K$E4 SG4P2JM6GCMU9FFSZAKNJH6ZNZVSWU78MHB4TO5J0N51U2F:17AB8O0*N0CQSA-9VIN904*STT$6R1LLXDT8J1ZN4I4368L02N72ZMGV496.0NO3OQCPFVF+C$BKQH1$+8L:AAEGRIB548B68D/3-ZTZ.JNM84E0F59$N6DY2*6FACA448900U42ZEMMO7-LO.45*IMXYIODF:82RN4L8Q%20HDJ-YCHIA1YT87A2/C1NO1F6DPCLCK9+BDXEEK23JH0/I8XJQEQ1T8BQ5GNDRFPQKKV6WT$A+98TIOUSAFA0J8OMY87$P-LESPS1KO+:O%HOY*C8XH4ZE7D16QR WNN$EP:U7E2HTLS023X0GJBW887LCKVHDGJ+Q88I0A73$H6R30XYH-LDC$4+24*JSE*H98A471BJ3:R0LU3MZA+ 4/GMZ9J D4E7L.TI$L8L:TN4G2S552748V$%D0CPH9RJ-7Z4AXFN*SS/ZC44O3P5%%AE936OUSR1H7WP%CP8KQUCY9I%A5FDBV+0A%HPVP5SKP9TKAFKT9FYROAABDBEHVQ9317O0D7MS5Z.Q2+K2.1RGGS3B5OTO2ROD60Z6LE98E94TV09JXM395VA0N.98EP3*4E5SHA7I96Q70UF74SPSIJI.BUHQJ$:K$9M51H9Z6RPHR.K-XT855UJJZC8C*MSITGMRE%O+:JQXV$LS7SJ1:DE LCX7RP7T JH4RR-NK.PASIWKA8J5Z1NA*BE7KFTJXO4BM5QVF.S0-5CG8KQWB8RCA1VP*1Q.ELZ1Q21G.JEGLOFH1:FR09$SCY/OGBU1QIE/2 9SK3" + let barcode = "HC1:NCFI.LUZB.P2YQ2E R002$DLTLIYXM/+0JNEAFUP.CV5GKCL /A0SQT/O8ZA85D0IJ$5D4.J+MR8-EGK6DM1R58V1ERUCWM4.E4ZM4$WG O E6KX9$KHCQMFE0B$KPKA*A2+ELQ*5ZQE/*1ZMSM5S.:KGQ33LQOWN67QW68LXM867D6837QCWEU*E*OKZCJPSCPIM1:Q83FBODLRD/W8K$E4 SG4P2JM6GCMU9FFSZAKNJH6ZNZVSWU78MHB4TO5J0N51U2F:17AB8O0*N0CQSA-9VIN904*STT$6R1LLXDT8J1ZN4I4368L02N72ZMGV496.0NO3OQCPFVF+C$BKQH1$+8L:AAEGRIB548B68D/3-ZTZ.JNM84E0F59$N6DY2*6FACA448900U42ZEMMO7-LO.45*IMXYIODF:82RN4L8Q%20HDJ-YCHIA1YT87A2/C1NO1F6DPCLCK9+BDXEEK23JH0/I8XJQEQ1T8BQ5GNDRFPQKKV6WT$A+98TIOUSAFA0J8OMY87$P-LESPS1KO+:O%HOY*C8XH4ZE7D16QR WNN$EP:U7E2HTLS023X0GJBW887LCKVHDGJ+Q88I0A73$H6R30XYH-LDC$4+24*JSE*H98A471BJ3:R0LU3MZA+ 4/GMZ9J D4E7L.TI$L8L:TN4G2S552748V$%D0CPH9RJ-7Z4AXFN*SS/ZC44O3P5%%AE936OUSR1H7WP%CP8KQUCY9I%A5FDBV+0A%HPVP5SKP9TKAFKT9FYROAABDBEHVQ9317O0D7MS5Z.Q2+K2.1RGGS3B5OTO2ROD60Z6LE98E94TV09JXM395VA0N.98EP3*4E5SHA7I96Q70UF74SPSIJI.BUHQJ$:K$9M51H9Z6RPHR.K-XT855UJJZC8C*MSITGMRE%O+:JQXV$LS7SJ1:DE LCX7RP7T JH4RR-NK.PASIWKA8J5Z1NA*BE7KFTJXO4BM5QVF.S0-5CG8KQWB8RCA1VP*1Q.ELZ1Q21G.JEGLOFH1:FR09$SCY/OGBU1QIE/2 9SK3" return baseTestAT(barcode: barcode) } func baseTestAT(barcode: String) { var barcode = barcode // Remove HC1 header if any - if (barcode.hasPrefix("HC1")) { - barcode = String(barcode.suffix(barcode.count-3)) + if (barcode.hasPrefix("HC1:")) { + barcode = String(barcode.suffix(barcode.count-4)) } guard From b783c6cccc4352521e1936879a9c36686fec90d5 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Mon, 19 Apr 2021 23:31:29 +0200 Subject: [PATCH 32/89] Display First Name. --- PatientScannerDemo/Models/HCert.swift | 6 ++++++ .../Storyboards/CertificateViewer.storyboard | 3 ++- PatientScannerDemo/SupportingFiles/Info.plist | 2 ++ .../ViewControllers/CertificateViewer.swift | 12 ++++++++++++ PatientScannerDemo/ViewControllers/Scan.swift | 17 +++++++++-------- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/PatientScannerDemo/Models/HCert.swift b/PatientScannerDemo/Models/HCert.swift index 1558068..a3b44ef 100644 --- a/PatientScannerDemo/Models/HCert.swift +++ b/PatientScannerDemo/Models/HCert.swift @@ -18,4 +18,10 @@ struct HCert { var header: JSON var body: JSON + + var fullName: String { + let first = body["-259"]["1"]["sub"]["gn"].string ?? "" + let last = body["-259"]["1"]["sub"]["fn"].string ?? "" + return "\(first) \(last)" + } } diff --git a/PatientScannerDemo/Storyboards/CertificateViewer.storyboard b/PatientScannerDemo/Storyboards/CertificateViewer.storyboard index df09785..dc5efc0 100644 --- a/PatientScannerDemo/Storyboards/CertificateViewer.storyboard +++ b/PatientScannerDemo/Storyboards/CertificateViewer.storyboard @@ -28,7 +28,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + diff --git a/PatientScannerDemo/ViewControllers/CertificateViewer.swift b/PatientScannerDemo/ViewControllers/CertificateViewer.swift index 2d23dfc..24516c2 100644 --- a/PatientScannerDemo/ViewControllers/CertificateViewer.swift +++ b/PatientScannerDemo/ViewControllers/CertificateViewer.swift @@ -11,12 +11,31 @@ import FloatingPanel let DISMISS_TIMEOUT = 15.0 +let validityString = [ + HCertValidity.valid: "Valid ✓", + HCertValidity.invalid: "Invalid Ⅹ", +] +let buttonText = [ + HCertValidity.valid: "Okay", + HCertValidity.invalid: "Retry", +] +let backgroundColor = [ + HCertValidity.valid: UIColor(red: 0, green: 0.32708, blue: 0.08872, alpha: 1), + HCertValidity.invalid: UIColor(red: 0.36290, green: 0, blue: 0, alpha: 1), +] +let textColor = [ + HCertValidity.valid: UIColor(red: 0.37632, green: 1, blue: 0.54549, alpha: 1), + HCertValidity.invalid: UIColor(red: 1, green: 0.14316, blue: 0.14316, alpha: 1), +] + class CertificateViewerVC: UIViewController { @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var validityLabel: UILabel! @IBOutlet weak var loadingBackground: UIView! @IBOutlet weak var loadingBackgroundTrailing: NSLayoutConstraint! @IBOutlet weak var typeSegments: UISegmentedControl! @IBOutlet weak var infoTable: UITableView! + @IBOutlet weak var dismissButton: UIButton! var hCert: HCert! { didSet { @@ -35,6 +54,11 @@ class CertificateViewerVC: UIViewController { HCertType.vaccineTwo, HCertType.recovery ].firstIndex(of: hCert.type) ?? 0 + let validity = hCert.validity + dismissButton.setTitle(buttonText[validity], for: .normal) + validityLabel.text = validityString[validity] + validityLabel.textColor = textColor[validity] + view.backgroundColor = backgroundColor[validity] } override func viewDidLoad() { diff --git a/PatientScannerDemo/ViewControllers/Scan.swift b/PatientScannerDemo/ViewControllers/Scan.swift index 0ed37e5..a9bc4cd 100644 --- a/PatientScannerDemo/ViewControllers/Scan.swift +++ b/PatientScannerDemo/ViewControllers/Scan.swift @@ -27,11 +27,11 @@ class ScanVC: UIViewController { override func viewDidLoad() { super.viewDidLoad() - checkPermissions() - setupCameraLiveView() -// DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { -// self.observationHandler(payloadS: nil) -// } +// checkPermissions() +// setupCameraLiveView() + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + self.observationHandler(payloadS: nil) + } } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) From 4d09682b8ef92d43fe9d3371e722b06ead87a6ae Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Wed, 21 Apr 2021 22:14:44 +0200 Subject: [PATCH 51/89] Colored button. --- PatientScannerDemo/ViewControllers/CertificateViewer.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PatientScannerDemo/ViewControllers/CertificateViewer.swift b/PatientScannerDemo/ViewControllers/CertificateViewer.swift index 24516c2..ee686a9 100644 --- a/PatientScannerDemo/ViewControllers/CertificateViewer.swift +++ b/PatientScannerDemo/ViewControllers/CertificateViewer.swift @@ -56,6 +56,8 @@ class CertificateViewerVC: UIViewController { ].firstIndex(of: hCert.type) ?? 0 let validity = hCert.validity dismissButton.setTitle(buttonText[validity], for: .normal) + dismissButton.backgroundColor = textColor[validity] + dismissButton.setTitleColor(backgroundColor[validity], for: .normal) validityLabel.text = validityString[validity] validityLabel.textColor = textColor[validity] view.backgroundColor = backgroundColor[validity] From e9288ec14b1ab528d49b04f88b663337388813d4 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Wed, 21 Apr 2021 22:21:06 +0200 Subject: [PATCH 52/89] Add DOB entry. --- PatientScannerDemo/Extensions/Date.swift | 8 ++++++++ PatientScannerDemo/Models/HCert.swift | 10 ++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/PatientScannerDemo/Extensions/Date.swift b/PatientScannerDemo/Extensions/Date.swift index 1539c68..42ec82f 100644 --- a/PatientScannerDemo/Extensions/Date.swift +++ b/PatientScannerDemo/Extensions/Date.swift @@ -44,4 +44,12 @@ extension Date { } self = date } + + var localDateString: String { + let formatter = DateFormatter() + formatter.locale = .current + formatter.timeStyle = .none + formatter.dateStyle = .medium + return formatter.string(from: self) + } } diff --git a/PatientScannerDemo/Models/HCert.swift b/PatientScannerDemo/Models/HCert.swift index 6d09e0e..859da74 100644 --- a/PatientScannerDemo/Models/HCert.swift +++ b/PatientScannerDemo/Models/HCert.swift @@ -128,9 +128,15 @@ struct HCert { } var info: [InfoSection] { - [ - InfoSection(header: "Certificate Type", content: type.rawValue) + var info = [ + InfoSection(header: "Certificate Type", content: type.rawValue), ] + personIdentifiers + if let date = dateOfBirth { + info += [ + InfoSection(header: "Date of Birth", content: date.localDateString), + ] + } + return info } var header: JSON From 17717a89abf2577d3fc7fa0e97c63b56334cf9f9 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 22 Apr 2021 22:43:28 +0200 Subject: [PATCH 53/89] Add license to all headers and header template. --- .../xcshareddata/IDETemplateMacros.plist | 34 +++++++++++++++++++ .../Components/FullFloatingPanelLayout.swift | 19 +++++++++++ PatientScannerDemo/Components/InfoCell.swift | 19 +++++++++++ .../Components/RoundedButton.swift | 19 +++++++++++ .../Components/SelfSizedTableView.swift | 19 +++++++++++ .../Extensions/Data+Base45.swift | 19 +++++++++++ .../Extensions/Data+hexString.swift | 19 +++++++++++ PatientScannerDemo/Extensions/Date.swift | 19 +++++++++++ .../Extensions/String+JSON.swift | 19 +++++++++++ PatientScannerDemo/Extensions/String.swift | 19 +++++++++++ .../Extensions/SwiftCBOR.CBOR.swift | 19 +++++++++++ PatientScannerDemo/Models/HCert.swift | 19 +++++++++++ .../Protocols/ChildDismissedDelegate.swift | 19 +++++++++++ PatientScannerDemo/Services/ASN1.swift | 19 +++++++++++ PatientScannerDemo/Services/Base45.swift | 19 +++++++++++ PatientScannerDemo/Services/CBOR.swift | 19 +++++++++++ PatientScannerDemo/Services/COSE.swift | 19 +++++++++++ PatientScannerDemo/Services/JWK.swift | 19 +++++++++++ PatientScannerDemo/Services/Signature.swift | 19 +++++++++++ PatientScannerDemo/Services/X509.swift | 19 +++++++++++ PatientScannerDemo/Services/ZLib.swift | 19 +++++++++++ .../SupportingFiles/AppDelegate.swift | 19 +++++++++++ .../SupportingFiles/EuDgcSchema.swift | 19 +++++++++++ .../SupportingFiles/SceneDelegate.swift | 19 +++++++++++ .../ViewControllers/CertificateViewer.swift | 19 +++++++++++ PatientScannerDemo/ViewControllers/Scan.swift | 19 +++++++++++ 26 files changed, 509 insertions(+) create mode 100644 PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist diff --git a/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist b/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist new file mode 100644 index 0000000..00155af --- /dev/null +++ b/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist @@ -0,0 +1,34 @@ + + + + + FILEHEADER + +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ +// +// ___FILENAME___ +// ___PACKAGENAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// + + + \ No newline at end of file diff --git a/PatientScannerDemo/Components/FullFloatingPanelLayout.swift b/PatientScannerDemo/Components/FullFloatingPanelLayout.swift index a599406..5f6983c 100644 --- a/PatientScannerDemo/Components/FullFloatingPanelLayout.swift +++ b/PatientScannerDemo/Components/FullFloatingPanelLayout.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // FullFloatingPanelLayout.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Components/InfoCell.swift b/PatientScannerDemo/Components/InfoCell.swift index c72de62..b27db3a 100644 --- a/PatientScannerDemo/Components/InfoCell.swift +++ b/PatientScannerDemo/Components/InfoCell.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // InfoCell.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Components/RoundedButton.swift b/PatientScannerDemo/Components/RoundedButton.swift index 2afdded..eb7aff0 100644 --- a/PatientScannerDemo/Components/RoundedButton.swift +++ b/PatientScannerDemo/Components/RoundedButton.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // RoundedButton.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Components/SelfSizedTableView.swift b/PatientScannerDemo/Components/SelfSizedTableView.swift index 81cda48..fc27401 100644 --- a/PatientScannerDemo/Components/SelfSizedTableView.swift +++ b/PatientScannerDemo/Components/SelfSizedTableView.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // SelfSizedTableView.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Extensions/Data+Base45.swift b/PatientScannerDemo/Extensions/Data+Base45.swift index 0105e67..3b7e7f4 100644 --- a/PatientScannerDemo/Extensions/Data+Base45.swift +++ b/PatientScannerDemo/Extensions/Data+Base45.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // Data+Base45.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Extensions/Data+hexString.swift b/PatientScannerDemo/Extensions/Data+hexString.swift index f283b8a..31a7060 100644 --- a/PatientScannerDemo/Extensions/Data+hexString.swift +++ b/PatientScannerDemo/Extensions/Data+hexString.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // Data+hexString.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Extensions/Date.swift b/PatientScannerDemo/Extensions/Date.swift index 42ec82f..cdd6385 100644 --- a/PatientScannerDemo/Extensions/Date.swift +++ b/PatientScannerDemo/Extensions/Date.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // Date.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Extensions/String+JSON.swift b/PatientScannerDemo/Extensions/String+JSON.swift index dc6414b..392957c 100644 --- a/PatientScannerDemo/Extensions/String+JSON.swift +++ b/PatientScannerDemo/Extensions/String+JSON.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // File.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Extensions/String.swift b/PatientScannerDemo/Extensions/String.swift index 0adc69e..699ab49 100644 --- a/PatientScannerDemo/Extensions/String.swift +++ b/PatientScannerDemo/Extensions/String.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // String.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift b/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift index d240400..46ad1a5 100644 --- a/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift +++ b/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // SwiftCBOR.CBOR.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Models/HCert.swift b/PatientScannerDemo/Models/HCert.swift index 859da74..674ff28 100644 --- a/PatientScannerDemo/Models/HCert.swift +++ b/PatientScannerDemo/Models/HCert.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // HCert.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift b/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift index 60691c0..5c8f831 100644 --- a/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift +++ b/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // ChildDismissedDelegate.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Services/ASN1.swift b/PatientScannerDemo/Services/ASN1.swift index badc02d..229eece 100644 --- a/PatientScannerDemo/Services/ASN1.swift +++ b/PatientScannerDemo/Services/ASN1.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // Asn1Encoder.swift // OegvatClient diff --git a/PatientScannerDemo/Services/Base45.swift b/PatientScannerDemo/Services/Base45.swift index 66cade7..83aeafe 100644 --- a/PatientScannerDemo/Services/Base45.swift +++ b/PatientScannerDemo/Services/Base45.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // Base45.swift // diff --git a/PatientScannerDemo/Services/CBOR.swift b/PatientScannerDemo/Services/CBOR.swift index 3af9f8d..01361a8 100644 --- a/PatientScannerDemo/Services/CBOR.swift +++ b/PatientScannerDemo/Services/CBOR.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // CBOR.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Services/COSE.swift b/PatientScannerDemo/Services/COSE.swift index 622a72b..4771689 100644 --- a/PatientScannerDemo/Services/COSE.swift +++ b/PatientScannerDemo/Services/COSE.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // COSE.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Services/JWK.swift b/PatientScannerDemo/Services/JWK.swift index fb7adba..2460202 100644 --- a/PatientScannerDemo/Services/JWK.swift +++ b/PatientScannerDemo/Services/JWK.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // JWK.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Services/Signature.swift b/PatientScannerDemo/Services/Signature.swift index d325818..5760792 100644 --- a/PatientScannerDemo/Services/Signature.swift +++ b/PatientScannerDemo/Services/Signature.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // EC256.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Services/X509.swift b/PatientScannerDemo/Services/X509.swift index 57af78a..465632b 100644 --- a/PatientScannerDemo/Services/X509.swift +++ b/PatientScannerDemo/Services/X509.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // X509.swift // PatientScannerDemo diff --git a/PatientScannerDemo/Services/ZLib.swift b/PatientScannerDemo/Services/ZLib.swift index 6eed4cc..d593ce1 100644 --- a/PatientScannerDemo/Services/ZLib.swift +++ b/PatientScannerDemo/Services/ZLib.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // https://stackoverflow.com/a/55558641/2585092 import Foundation diff --git a/PatientScannerDemo/SupportingFiles/AppDelegate.swift b/PatientScannerDemo/SupportingFiles/AppDelegate.swift index 9e403d6..2650937 100644 --- a/PatientScannerDemo/SupportingFiles/AppDelegate.swift +++ b/PatientScannerDemo/SupportingFiles/AppDelegate.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // AppDelegate.swift // PatientScannerDemo diff --git a/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift b/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift index a51a63b..56e8d50 100644 --- a/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift +++ b/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // EuDgcSchema.swift // PatientScannerDemo diff --git a/PatientScannerDemo/SupportingFiles/SceneDelegate.swift b/PatientScannerDemo/SupportingFiles/SceneDelegate.swift index ef39680..df3172a 100644 --- a/PatientScannerDemo/SupportingFiles/SceneDelegate.swift +++ b/PatientScannerDemo/SupportingFiles/SceneDelegate.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // SceneDelegate.swift // PatientScannerDemo diff --git a/PatientScannerDemo/ViewControllers/CertificateViewer.swift b/PatientScannerDemo/ViewControllers/CertificateViewer.swift index ee686a9..c798cc1 100644 --- a/PatientScannerDemo/ViewControllers/CertificateViewer.swift +++ b/PatientScannerDemo/ViewControllers/CertificateViewer.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // CertificateViewer.swift // PatientScannerDemo diff --git a/PatientScannerDemo/ViewControllers/Scan.swift b/PatientScannerDemo/ViewControllers/Scan.swift index a9bc4cd..79f2c38 100644 --- a/PatientScannerDemo/ViewControllers/Scan.swift +++ b/PatientScannerDemo/ViewControllers/Scan.swift @@ -1,3 +1,22 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-web + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ // // ViewController.swift // PatientScannerDemo From 992ec134830f02e3e2b00b85c7629ac822dbf013 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 22 Apr 2021 22:46:51 +0200 Subject: [PATCH 54/89] Change notice. --- NOTICE | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NOTICE b/NOTICE index d7bf1bb..77c2a9b 100644 --- a/NOTICE +++ b/NOTICE @@ -7,4 +7,5 @@ Contributors: ------------- Daniel Eder [daniel-eder], T-Mobile International Austria GmbH -Andreas Scheibal [ascheibal], T-Systems International GmbH \ No newline at end of file +Andreas Scheibal [ascheibal], T-Systems International GmbH +Yannick Spreen [yspreen], yspreen.com \ No newline at end of file From 7cc97a4b0d92f4db3c567243ced4354021e60813 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 22 Apr 2021 22:49:32 +0200 Subject: [PATCH 55/89] Add project name to header. --- .../xcshareddata/IDETemplateMacros.plist | 2 +- .../Components/FullFloatingPanelLayout.swift | 2 +- PatientScannerDemo/Components/InfoCell.swift | 2 +- PatientScannerDemo/Components/RoundedButton.swift | 2 +- PatientScannerDemo/Components/SelfSizedTableView.swift | 2 +- PatientScannerDemo/Extensions/Data+Base45.swift | 2 +- PatientScannerDemo/Extensions/Data+hexString.swift | 2 +- PatientScannerDemo/Extensions/Date.swift | 2 +- PatientScannerDemo/Extensions/String+JSON.swift | 2 +- PatientScannerDemo/Extensions/String.swift | 2 +- PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift | 2 +- PatientScannerDemo/Models/HCert.swift | 2 +- PatientScannerDemo/Protocols/ChildDismissedDelegate.swift | 2 +- PatientScannerDemo/Services/ASN1.swift | 2 +- PatientScannerDemo/Services/Base45.swift | 2 +- PatientScannerDemo/Services/CBOR.swift | 2 +- PatientScannerDemo/Services/COSE.swift | 2 +- PatientScannerDemo/Services/JWK.swift | 2 +- PatientScannerDemo/Services/Signature.swift | 2 +- PatientScannerDemo/Services/X509.swift | 2 +- PatientScannerDemo/Services/ZLib.swift | 2 +- PatientScannerDemo/SupportingFiles/AppDelegate.swift | 2 +- PatientScannerDemo/SupportingFiles/EuDgcSchema.swift | 2 +- PatientScannerDemo/SupportingFiles/SceneDelegate.swift | 2 +- .../ViewControllers/CertificateViewer.swift | 2 +- PatientScannerDemo/ViewControllers/Scan.swift | 2 +- templates/file-header.txt | 8 +++++++- 27 files changed, 33 insertions(+), 27 deletions(-) diff --git a/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist b/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist index 00155af..5ef75dc 100644 --- a/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist +++ b/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist @@ -6,7 +6,7 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Components/FullFloatingPanelLayout.swift b/PatientScannerDemo/Components/FullFloatingPanelLayout.swift index 5f6983c..205e4b9 100644 --- a/PatientScannerDemo/Components/FullFloatingPanelLayout.swift +++ b/PatientScannerDemo/Components/FullFloatingPanelLayout.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Components/InfoCell.swift b/PatientScannerDemo/Components/InfoCell.swift index b27db3a..fbe680b 100644 --- a/PatientScannerDemo/Components/InfoCell.swift +++ b/PatientScannerDemo/Components/InfoCell.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Components/RoundedButton.swift b/PatientScannerDemo/Components/RoundedButton.swift index eb7aff0..c928291 100644 --- a/PatientScannerDemo/Components/RoundedButton.swift +++ b/PatientScannerDemo/Components/RoundedButton.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Components/SelfSizedTableView.swift b/PatientScannerDemo/Components/SelfSizedTableView.swift index fc27401..a69ea86 100644 --- a/PatientScannerDemo/Components/SelfSizedTableView.swift +++ b/PatientScannerDemo/Components/SelfSizedTableView.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Extensions/Data+Base45.swift b/PatientScannerDemo/Extensions/Data+Base45.swift index 3b7e7f4..7eb0322 100644 --- a/PatientScannerDemo/Extensions/Data+Base45.swift +++ b/PatientScannerDemo/Extensions/Data+Base45.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Extensions/Data+hexString.swift b/PatientScannerDemo/Extensions/Data+hexString.swift index 31a7060..9914aa4 100644 --- a/PatientScannerDemo/Extensions/Data+hexString.swift +++ b/PatientScannerDemo/Extensions/Data+hexString.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Extensions/Date.swift b/PatientScannerDemo/Extensions/Date.swift index cdd6385..19e8687 100644 --- a/PatientScannerDemo/Extensions/Date.swift +++ b/PatientScannerDemo/Extensions/Date.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Extensions/String+JSON.swift b/PatientScannerDemo/Extensions/String+JSON.swift index 392957c..d8f495a 100644 --- a/PatientScannerDemo/Extensions/String+JSON.swift +++ b/PatientScannerDemo/Extensions/String+JSON.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Extensions/String.swift b/PatientScannerDemo/Extensions/String.swift index 699ab49..928027d 100644 --- a/PatientScannerDemo/Extensions/String.swift +++ b/PatientScannerDemo/Extensions/String.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift b/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift index 46ad1a5..607ba0f 100644 --- a/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift +++ b/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Models/HCert.swift b/PatientScannerDemo/Models/HCert.swift index 674ff28..daa2ae1 100644 --- a/PatientScannerDemo/Models/HCert.swift +++ b/PatientScannerDemo/Models/HCert.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift b/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift index 5c8f831..076d8d6 100644 --- a/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift +++ b/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Services/ASN1.swift b/PatientScannerDemo/Services/ASN1.swift index 229eece..bef10f5 100644 --- a/PatientScannerDemo/Services/ASN1.swift +++ b/PatientScannerDemo/Services/ASN1.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Services/Base45.swift b/PatientScannerDemo/Services/Base45.swift index 83aeafe..00e9c14 100644 --- a/PatientScannerDemo/Services/Base45.swift +++ b/PatientScannerDemo/Services/Base45.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Services/CBOR.swift b/PatientScannerDemo/Services/CBOR.swift index 01361a8..0e0c8af 100644 --- a/PatientScannerDemo/Services/CBOR.swift +++ b/PatientScannerDemo/Services/CBOR.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Services/COSE.swift b/PatientScannerDemo/Services/COSE.swift index 4771689..a7e8098 100644 --- a/PatientScannerDemo/Services/COSE.swift +++ b/PatientScannerDemo/Services/COSE.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Services/JWK.swift b/PatientScannerDemo/Services/JWK.swift index 2460202..cd36a4c 100644 --- a/PatientScannerDemo/Services/JWK.swift +++ b/PatientScannerDemo/Services/JWK.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Services/Signature.swift b/PatientScannerDemo/Services/Signature.swift index 5760792..c1f6737 100644 --- a/PatientScannerDemo/Services/Signature.swift +++ b/PatientScannerDemo/Services/Signature.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Services/X509.swift b/PatientScannerDemo/Services/X509.swift index 465632b..1d482bc 100644 --- a/PatientScannerDemo/Services/X509.swift +++ b/PatientScannerDemo/Services/X509.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/Services/ZLib.swift b/PatientScannerDemo/Services/ZLib.swift index d593ce1..0fdc739 100644 --- a/PatientScannerDemo/Services/ZLib.swift +++ b/PatientScannerDemo/Services/ZLib.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/SupportingFiles/AppDelegate.swift b/PatientScannerDemo/SupportingFiles/AppDelegate.swift index 2650937..9272256 100644 --- a/PatientScannerDemo/SupportingFiles/AppDelegate.swift +++ b/PatientScannerDemo/SupportingFiles/AppDelegate.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift b/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift index 56e8d50..bd43548 100644 --- a/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift +++ b/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/SupportingFiles/SceneDelegate.swift b/PatientScannerDemo/SupportingFiles/SceneDelegate.swift index df3172a..e561605 100644 --- a/PatientScannerDemo/SupportingFiles/SceneDelegate.swift +++ b/PatientScannerDemo/SupportingFiles/SceneDelegate.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/ViewControllers/CertificateViewer.swift b/PatientScannerDemo/ViewControllers/CertificateViewer.swift index c798cc1..4c202af 100644 --- a/PatientScannerDemo/ViewControllers/CertificateViewer.swift +++ b/PatientScannerDemo/ViewControllers/CertificateViewer.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/PatientScannerDemo/ViewControllers/Scan.swift b/PatientScannerDemo/ViewControllers/Scan.swift index 79f2c38..6504f80 100644 --- a/PatientScannerDemo/ViewControllers/Scan.swift +++ b/PatientScannerDemo/ViewControllers/Scan.swift @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- diff --git a/templates/file-header.txt b/templates/file-header.txt index 9ffd499..1adb99e 100644 --- a/templates/file-header.txt +++ b/templates/file-header.txt @@ -1,6 +1,6 @@ /*- * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-web + * eu-digital-green-certificates / dgca-verifier-app-ios * --- * Copyright (C) 2021 T-Systems International GmbH and all other contributors * --- @@ -17,3 +17,9 @@ * limitations under the License. * ---license-end */ +// +// ___FILENAME___ +// ___PACKAGENAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// From ba4173f34e2a0ca66bc5857fd2fc951df204bc12 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 22 Apr 2021 23:03:59 +0200 Subject: [PATCH 56/89] Fix tests. --- PatientScannerDemo.xcodeproj/project.pbxproj | 4 +++ PatientScannerDemo/Services/KID.swift | 35 +++++++++++++++++++ PatientScannerDemo/ViewControllers/Scan.swift | 20 +++++++++++ PatientScannerDemoTests/EHNTests.swift | 15 +++++--- 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 PatientScannerDemo/Services/KID.swift diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index f5127a5..4addceb 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ CE44799226306C86009A836B /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE44799126306C86009A836B /* String.swift */; }; CE44799726306C9B009A836B /* Data+Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE44799626306C9B009A836B /* Data+Base45.swift */; }; CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CE7DE7F92625EF18007E6694 /* SwiftCBOR */; }; + CE8912E526321AA500CB92AF /* KID.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE8912E426321AA500CB92AF /* KID.swift */; }; CEA1555D262F63B30024B7AC /* EuDgcSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA1555C262F63B30024B7AC /* EuDgcSchema.swift */; }; CEA15563262F6DAB0024B7AC /* ChildDismissedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA15562262F6DAB0024B7AC /* ChildDismissedDelegate.swift */; }; CEA1556B262F784E0024B7AC /* SelfSizedTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA1556A262F784E0024B7AC /* SelfSizedTableView.swift */; }; @@ -75,6 +76,7 @@ CE3CC9432628C2130079FB78 /* CBOR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBOR.swift; sourceTree = ""; }; CE44799126306C86009A836B /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; }; CE44799626306C9B009A836B /* Data+Base45.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Base45.swift"; sourceTree = ""; }; + CE8912E426321AA500CB92AF /* KID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KID.swift; sourceTree = ""; }; CEA1555C262F63B30024B7AC /* EuDgcSchema.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EuDgcSchema.swift; sourceTree = ""; }; CEA15562262F6DAB0024B7AC /* ChildDismissedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChildDismissedDelegate.swift; sourceTree = ""; }; CEA1556A262F784E0024B7AC /* SelfSizedTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelfSizedTableView.swift; sourceTree = ""; }; @@ -153,6 +155,7 @@ CEFAD87926271414009AFEF9 /* COSE.swift */, CE3CC9432628C2130079FB78 /* CBOR.swift */, CE1BDF98262A4CD600766F97 /* X509.swift */, + CE8912E426321AA500CB92AF /* KID.swift */, ); path = Services; sourceTree = ""; @@ -439,6 +442,7 @@ CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */, CEA15570262F79DE0024B7AC /* InfoCell.swift in Sources */, CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */, + CE8912E526321AA500CB92AF /* KID.swift in Sources */, CE157F9B262E2A9F00FE4821 /* SwiftCBOR.CBOR.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/PatientScannerDemo/Services/KID.swift b/PatientScannerDemo/Services/KID.swift new file mode 100644 index 0000000..81bf340 --- /dev/null +++ b/PatientScannerDemo/Services/KID.swift @@ -0,0 +1,35 @@ +// +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-ios + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ +// +// KID.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/22/21. +// + + +import Foundation + +struct KID { + public static func stringFrom(kidBytes: [UInt8]) -> String { + return Data(kidBytes.prefix(8)).base64EncodedString() + } +} diff --git a/PatientScannerDemo/ViewControllers/Scan.swift b/PatientScannerDemo/ViewControllers/Scan.swift index 6504f80..49a3464 100644 --- a/PatientScannerDemo/ViewControllers/Scan.swift +++ b/PatientScannerDemo/ViewControllers/Scan.swift @@ -31,6 +31,7 @@ import Vision import AVFoundation import SwiftCBOR import FloatingPanel +import LocalAuthentication class ScanVC: UIViewController { @@ -50,6 +51,25 @@ class ScanVC: UIViewController { // setupCameraLiveView() DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.observationHandler(payloadS: nil) +// let reason = "Log in to your account" +// var context = LAContext() +// context.localizedCancelTitle = "Enter Username/Password" +// context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason ) { success, error in +// +// if success { +// +// // Move to the main thread because a state update triggers UI changes. +// DispatchQueue.main.async { [unowned self] in +// print("loggedin") +// } +// +// } else { +// print(error?.localizedDescription ?? "Failed to authenticate") +// +// // Fall back to a asking for username and password. +// // ... +// } +// } } } override func viewWillDisappear(_ animated: Bool) { diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index 391a691..23e31a4 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -75,11 +75,11 @@ class EHNTests: XCTestCase { XCTAssert(false) } func testCoseEcAT() throws { - let barcode = "HC1:NCFI.L3B6AP2YQ2%MNBCHC51/CAOZDL+OL7S99U60SVOGSHD%24R4PCTH7Y9KL6EVJBIMBL364D X1KKLZ*I9K4RLDR7B011EROZS6022WR5VX4QG9W72HWCC12B:TWZG.%N8GWBCOV0O%5F9U7H 8P4L.%2/:6TXB/-J6ZJ.*QYIBYSD6/T.6RDMMK0PX6HTPO1REO*CWMFG5CJ38+FBS+8DB9*2FFP9Z8HEM137CRBQ.893$I.R7 DRFOVMUQRVDP4IU613/G-0LZ:43+MM:QO.CQPJU21-7PJ*L/*DVLO:Q5G-7%WF4ZO*JJR:KH+O1707M6.73VXG0+0050+IMIFH:3V+DL3JK/21/LEI$T5TUT8P:40P10AXGBRS%-GZS8TGF-IT3-HU2SVJUAVG%AGO98R00Y.QT23DVP0TB*-J6YJP 8TU9U/OJSQGGMK+K3MH IR U7H%9/UU07AGEWMVTOBAYIV4SPGC2Y5FJJ67I4/J4FXM3GP:SAOZQJPL%WGP4BT59Q8K5MB*M44%K9JTWB9K+LS-2I9ST+3J%0X%1YGN0E0KL3/FHTZHEF9WIC4Q1HVK74L186BWT9+TJR7C2M%9JXN8S%0PVU8GFBET%0PG RR1KD2F11G-CW8A4124N9VN-T-:292AX*B%ER*$12-O:6K:/N$ 7IYFFXQ/5F NC49M/W5501B2OKU7E:NHMM8SETWUK*I$JR" + let barcode = "HC1:NCFC:M/8OBK2 53WGEI1J%1IEAKE%GKV5B8M38S78UU+RRIR+1CT013E9ZI8$*NVQE+PQKR434V:-NN551/A*HSD87*JGTPKU77HTHOTIY/9VPKP859+1Q-1JCFL:O8SBM:5I%7X2NRAQ1XL0$E867W1FH-NIAWOQJEFELCNXMT7S739DJ2G2*CYG9IEMEU7/.B%E9 $0DKJPRIK-RRX2WBPOFE32TW HL24/YI4SO5LF04NZ-D O9$K9$IHYTC4JB622YMQ.5LVXH64JFGG-L0LJTW88O.L5T48AW2MTJD8CL4OUE4V2HX88FAH 89NKJS2SMPU%I8OC0AEPJ0 F2SMTERNC7CM20P00C9L8MBI.PMP9WWG6ICY$FK/QARHN+JX8S24UU00CEAA:SQUTY0LPRGQXVN6Q*UR-WH/FC8CJQ8WLBJH$47O8+.GMF78*A85H1GU4SPNC3TVKQBK:7C836%WI/QR$EC0YE:E77%LHAE5T07AVLUPLW38MMNF00 CE9U$-VKYU ZN1V3C:M9YH.RDK%VQSC.GRN29JSENCEX7SQ.J6:4D28Z*E*3V5/R6Q7*:3I R+1GUZQ$LBB 7B-E2KTU/0X1B- UKUJJ2U0.H 0RM2GBGIQ+M" return baseTestAT(barcode: barcode) } func testCoseRsaAT() throws { - let barcode = "HC1:NCFI.LUZB.P2YQ2E R002$DLTLIYXM/+0JNEAFUP.CV5GKCL /A0SQT/O8ZA85D0IJ$5D4.J+MR8-EGK6DM1R58V1ERUCWM4.E4ZM4$WG O E6KX9$KHCQMFE0B$KPKA*A2+ELQ*5ZQE/*1ZMSM5S.:KGQ33LQOWN67QW68LXM867D6837QCWEU*E*OKZCJPSCPIM1:Q83FBODLRD/W8K$E4 SG4P2JM6GCMU9FFSZAKNJH6ZNZVSWU78MHB4TO5J0N51U2F:17AB8O0*N0CQSA-9VIN904*STT$6R1LLXDT8J1ZN4I4368L02N72ZMGV496.0NO3OQCPFVF+C$BKQH1$+8L:AAEGRIB548B68D/3-ZTZ.JNM84E0F59$N6DY2*6FACA448900U42ZEMMO7-LO.45*IMXYIODF:82RN4L8Q%20HDJ-YCHIA1YT87A2/C1NO1F6DPCLCK9+BDXEEK23JH0/I8XJQEQ1T8BQ5GNDRFPQKKV6WT$A+98TIOUSAFA0J8OMY87$P-LESPS1KO+:O%HOY*C8XH4ZE7D16QR WNN$EP:U7E2HTLS023X0GJBW887LCKVHDGJ+Q88I0A73$H6R30XYH-LDC$4+24*JSE*H98A471BJ3:R0LU3MZA+ 4/GMZ9J D4E7L.TI$L8L:TN4G2S552748V$%D0CPH9RJ-7Z4AXFN*SS/ZC44O3P5%%AE936OUSR1H7WP%CP8KQUCY9I%A5FDBV+0A%HPVP5SKP9TKAFKT9FYROAABDBEHVQ9317O0D7MS5Z.Q2+K2.1RGGS3B5OTO2ROD60Z6LE98E94TV09JXM395VA0N.98EP3*4E5SHA7I96Q70UF74SPSIJI.BUHQJ$:K$9M51H9Z6RPHR.K-XT855UJJZC8C*MSITGMRE%O+:JQXV$LS7SJ1:DE LCX7RP7T JH4RR-NK.PASIWKA8J5Z1NA*BE7KFTJXO4BM5QVF.S0-5CG8KQWB8RCA1VP*1Q.ELZ1Q21G.JEGLOFH1:FR09$SCY/OGBU1QIE/2 9SK3" + let barcode = "HC1:NCFOXNYTS3DH$YO:CQSU40 H 804 2FI15B3LR5OGILG9N:5-RII9DL-VAD65D6 NI4EFFZSE+S.SSH2HGUS XKVD9HB58QHVM6IQ17XH0S9S-JX%EI$HGL24EGYJ2SKISE02UQHPMYO9MN9JUHLKH.O93UQFJ6GL28LHXOAYJAPRAAUICO10W59UE1YHU-H4PIUF2VSJGV4J4LV/AYVG2$436D$X40YC2ATNS4Y6TKR2*G5C%CO8TJV4423 L0VV2 73-E3ND3DAJ-432$4U1JS.S./0LWTKD33236J3TA3E-4%:K7-SN2H N37J3JFTULJ5CBP:2C 2+*4HTC/2DBAJDAJCNB-43GV4MCTKD08DJHSI PISVDGZK4EC8.SX1LC8C8DJOMI$MI-N09*0245$UH8QIBD2GMJCKH9AO2R7./HBR6$LE KMDGKRFRSGHQED10H% 0R%0D 8YIPFHL:OTEGJUY25$0P/HX$4T0H//CI+CF/8-0LO1PX$4D4TVZ0D-4VZ0S1LZ0L:M623Q$B65VCNAIO38ZIIT-ROGV86O*$2/6PSQHV-P TN3H38EU2VME.3F$MM3WYC3A1N%IFBZV3P6$A9X81M:L-5TTPNFIVD6KL/O63UX0O7V9BYEB:IB BUAA9JM:ATN.AR81Y4GP21CPVY6P:KPG:LNLL%70/6MRVMT0LV0E7*EVLS2UIU6V2M3%26%Q3J*H:5L-28SXRWUH$LCQ/S3QTY5NG.8C5MN$V4-BXJMF5RG3U6-1RDVRWNY$3/ZB3MOQDWC*08M0AV5*/0QX4B-EF0MGH5X1FYHRGX8:+RY/EI%BQ95TC5*DW/ESR4S0:1ZF59*5GK1-OH4Z6-6FUOTN*H$38IPR4GT1$OE07B*SWKN*HF83N MO.CFOW3R%GB28Z$UOH7DROI9BW/CXPS0.PS USQE:LAVZP320%R902" return baseTestAT(barcode: barcode) } func baseTestAT(barcode: String) { @@ -99,9 +99,14 @@ class EHNTests: XCTestCase { let data = decompress(compressed) guard - let kidBytes = CBOR.kid(from: data), - let kid = String(data: Data(kidBytes), encoding: .utf8), - let url = URL(string: "https://dev.a-sit.at/certservice/cert/\(kid)") + let kidBytes = CBOR.kid(from: data) + else { + XCTAssert(false) + return + } + let kid = KID.stringFrom(kidBytes: kidBytes) + guard + let url = URL(string: "https://dgc.a-sit.at/ehn/cert/\(kid)") else { XCTAssert(false) return From 5cf17f0e7a2bff77848a5ed460577e2479b5dd1a Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 22 Apr 2021 23:16:10 +0200 Subject: [PATCH 57/89] Add KID validation. --- PatientScannerDemo.xcodeproj/project.pbxproj | 4 ++ .../xcshareddata/IDETemplateMacros.plist | 12 +++--- PatientScannerDemo/Services/KID.swift | 14 +++++-- PatientScannerDemo/Services/SHA256.swift | 40 +++++++++++++++++++ PatientScannerDemoTests/EHNTests.swift | 2 +- templates/file-header.txt | 12 +++--- 6 files changed, 68 insertions(+), 16 deletions(-) create mode 100644 PatientScannerDemo/Services/SHA256.swift diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/PatientScannerDemo.xcodeproj/project.pbxproj index 4addceb..e5b7c70 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/PatientScannerDemo.xcodeproj/project.pbxproj @@ -24,6 +24,7 @@ CE44799726306C9B009A836B /* Data+Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE44799626306C9B009A836B /* Data+Base45.swift */; }; CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CE7DE7F92625EF18007E6694 /* SwiftCBOR */; }; CE8912E526321AA500CB92AF /* KID.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE8912E426321AA500CB92AF /* KID.swift */; }; + CE8912EA26321DAA00CB92AF /* SHA256.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE8912E926321DAA00CB92AF /* SHA256.swift */; }; CEA1555D262F63B30024B7AC /* EuDgcSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA1555C262F63B30024B7AC /* EuDgcSchema.swift */; }; CEA15563262F6DAB0024B7AC /* ChildDismissedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA15562262F6DAB0024B7AC /* ChildDismissedDelegate.swift */; }; CEA1556B262F784E0024B7AC /* SelfSizedTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA1556A262F784E0024B7AC /* SelfSizedTableView.swift */; }; @@ -77,6 +78,7 @@ CE44799126306C86009A836B /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; }; CE44799626306C9B009A836B /* Data+Base45.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Base45.swift"; sourceTree = ""; }; CE8912E426321AA500CB92AF /* KID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KID.swift; sourceTree = ""; }; + CE8912E926321DAA00CB92AF /* SHA256.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SHA256.swift; sourceTree = ""; }; CEA1555C262F63B30024B7AC /* EuDgcSchema.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EuDgcSchema.swift; sourceTree = ""; }; CEA15562262F6DAB0024B7AC /* ChildDismissedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChildDismissedDelegate.swift; sourceTree = ""; }; CEA1556A262F784E0024B7AC /* SelfSizedTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelfSizedTableView.swift; sourceTree = ""; }; @@ -156,6 +158,7 @@ CE3CC9432628C2130079FB78 /* CBOR.swift */, CE1BDF98262A4CD600766F97 /* X509.swift */, CE8912E426321AA500CB92AF /* KID.swift */, + CE8912E926321DAA00CB92AF /* SHA256.swift */, ); path = Services; sourceTree = ""; @@ -423,6 +426,7 @@ CE13CF0A262DCDDA0070C80E /* CertificateViewer.swift in Sources */, CEC2C4C32625ED030056E406 /* JWK.swift in Sources */, CEC2C4C42625ED030056E406 /* Base45.swift in Sources */, + CE8912EA26321DAA00CB92AF /* SHA256.swift in Sources */, CE3CC9442628C2130079FB78 /* CBOR.swift in Sources */, CE44799226306C86009A836B /* String.swift in Sources */, CE44799726306C9B009A836B /* Data+Base45.swift in Sources */, diff --git a/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist b/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist index 5ef75dc..deb1c68 100644 --- a/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist +++ b/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist @@ -23,12 +23,12 @@ * limitations under the License. * ---license-end */ -// -// ___FILENAME___ -// ___PACKAGENAME___ -// -// Created by ___FULLUSERNAME___ on ___DATE___. -// +// +// ___FILENAME___ +// ___PACKAGENAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// \ No newline at end of file diff --git a/PatientScannerDemo/Services/KID.swift b/PatientScannerDemo/Services/KID.swift index 81bf340..a18ab40 100644 --- a/PatientScannerDemo/Services/KID.swift +++ b/PatientScannerDemo/Services/KID.swift @@ -19,10 +19,10 @@ * ---license-end */ // -// KID.swift -// PatientScannerDemo +// KID.swift +// PatientScannerDemo // -// Created by Yannick Spreen on 4/22/21. +// Created by Yannick Spreen on 4/22/21. // @@ -32,4 +32,12 @@ struct KID { public static func stringFrom(kidBytes: [UInt8]) -> String { return Data(kidBytes.prefix(8)).base64EncodedString() } + public static func from(_ encodedCert: String) -> [UInt8] { + guard + let data = Data(base64Encoded: encodedCert) + else { + return [] + } + return SHA256.digest(input: data as NSData).uint + } } diff --git a/PatientScannerDemo/Services/SHA256.swift b/PatientScannerDemo/Services/SHA256.swift new file mode 100644 index 0000000..57fb5f8 --- /dev/null +++ b/PatientScannerDemo/Services/SHA256.swift @@ -0,0 +1,40 @@ +// +/*- + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-ios + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ +// +// SHA256.swift +// PatientScannerDemo +// +// Created by Yannick Spreen on 4/22/21. +// +// https://stackoverflow.com/a/38788437/2585092 +// + +import Foundation +import CommonCrypto + +struct SHA256 { + public static func digest(input: NSData) -> Data { + let digestLength = Int(CC_SHA256_DIGEST_LENGTH) + var hash = [UInt8](repeating: 0, count: digestLength) + CC_SHA256(input.bytes, UInt32(input.length), &hash) + return Data(NSData(bytes: hash, length: digestLength)) + } +} diff --git a/PatientScannerDemoTests/EHNTests.swift b/PatientScannerDemoTests/EHNTests.swift index 23e31a4..7fbac13 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/PatientScannerDemoTests/EHNTests.swift @@ -8,7 +8,6 @@ @testable import PatientScannerDemo import XCTest - class EHNTests: XCTestCase { func testCoseEcdsa() throws { var barcode = "HC1:NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5" @@ -123,6 +122,7 @@ class EHNTests: XCTestCase { return } let encodedCert = body.base64EncodedString() + XCTAssert(KID.stringFrom(kidBytes: KID.from(encodedCert)) == kid) if COSE.verify(data, with: encodedCert) { expectation.fulfill() } else { diff --git a/templates/file-header.txt b/templates/file-header.txt index 1adb99e..55ce82f 100644 --- a/templates/file-header.txt +++ b/templates/file-header.txt @@ -17,9 +17,9 @@ * limitations under the License. * ---license-end */ -// -// ___FILENAME___ -// ___PACKAGENAME___ -// -// Created by ___FULLUSERNAME___ on ___DATE___. -// +// +// ___FILENAME___ +// ___PACKAGENAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// From 486d63b2b560f73a03427ed8b2ea0fa6fede1870 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Thu, 22 Apr 2021 23:17:41 +0200 Subject: [PATCH 58/89] Add typealias. --- PatientScannerDemo/Services/KID.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/PatientScannerDemo/Services/KID.swift b/PatientScannerDemo/Services/KID.swift index a18ab40..ab954c4 100644 --- a/PatientScannerDemo/Services/KID.swift +++ b/PatientScannerDemo/Services/KID.swift @@ -28,11 +28,13 @@ import Foundation +typealias KidBytes = [UInt8] + struct KID { - public static func stringFrom(kidBytes: [UInt8]) -> String { + public static func stringFrom(kidBytes: KidBytes) -> String { return Data(kidBytes.prefix(8)).base64EncodedString() } - public static func from(_ encodedCert: String) -> [UInt8] { + public static func from(_ encodedCert: String) -> KidBytes { guard let data = Data(base64Encoded: encodedCert) else { From 429ccd7527447e20de33be6a83f92abb43a82e97 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Fri, 23 Apr 2021 09:01:41 +0200 Subject: [PATCH 59/89] Fix KID length. --- PatientScannerDemo/Services/KID.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PatientScannerDemo/Services/KID.swift b/PatientScannerDemo/Services/KID.swift index ab954c4..8d36807 100644 --- a/PatientScannerDemo/Services/KID.swift +++ b/PatientScannerDemo/Services/KID.swift @@ -40,6 +40,6 @@ struct KID { else { return [] } - return SHA256.digest(input: data as NSData).uint + return .init(SHA256.digest(input: data as NSData).uint.prefix(8)) } } From f6c23ea36b917014d1aa2a228e74584ac9075144 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Fri, 23 Apr 2021 11:22:55 +0200 Subject: [PATCH 60/89] Remove sensitive print. --- PatientScannerDemo/Models/HCert.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PatientScannerDemo/Models/HCert.swift b/PatientScannerDemo/Models/HCert.swift index daa2ae1..20ecd7a 100644 --- a/PatientScannerDemo/Models/HCert.swift +++ b/PatientScannerDemo/Models/HCert.swift @@ -114,7 +114,7 @@ struct HCert { } #endif print(header) - print(body) +// print(body) return true } @@ -123,7 +123,7 @@ struct HCert { let bodyStr = CBOR.payload(from: cborData)?.toString() ?? "{}" header = JSON(parseJSON: headerStr) var body = JSON(parseJSON: bodyStr) - print(body) +// print(body) if body[ClaimKey.HCERT.rawValue].exists() { body = body[ClaimKey.HCERT.rawValue] } From dcd95c87ce58ea894b7ba068ddf3df4b95e2e765 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Sun, 25 Apr 2021 14:09:33 +0200 Subject: [PATCH 61/89] Rename Project. --- .../project.pbxproj | 118 +++++++++--------- .../contents.xcworkspacedata | 2 +- .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/swiftpm/Package.resolved | 0 .../xcshareddata/IDETemplateMacros.plist | 0 .../xcschemes/DGCAVerifier.xcscheme | 98 +++++++++++++++ .../Components/FullFloatingPanelLayout.swift | 2 +- .../Components/InfoCell.swift | 2 +- .../Components/RoundedButton.swift | 2 +- .../Components/SelfSizedTableView.swift | 2 +- .../Extensions/Data+Base45.swift | 2 +- .../Extensions/Data+hexString.swift | 2 +- .../Extensions/Date.swift | 2 +- .../Extensions/String+JSON.swift | 2 +- .../Extensions/String.swift | 2 +- .../Extensions/SwiftCBOR.CBOR.swift | 2 +- .../Models/HCert.swift | 2 +- .../Protocols/ChildDismissedDelegate.swift | 2 +- .../Services/ASN1.swift | 0 .../Services/Base45.swift | 0 .../Services/CBOR.swift | 2 +- .../Services/COSE.swift | 2 +- .../Services/JWK.swift | 2 +- .../Services/KID.swift | 2 +- .../Services/SHA256.swift | 2 +- .../Services/Signature.swift | 2 +- .../Services/X509.swift | 2 +- .../Services/ZLib.swift | 0 .../Base.lproj/LaunchScreen.storyboard | 18 ++- .../Storyboards/Base.lproj/Main.storyboard | 2 +- .../Storyboards/CertificateViewer.storyboard | 0 .../SupportingFiles/AppDelegate.swift | 2 +- .../AccentColor.colorset/Contents.json | 0 .../AppIcon.appiconset/Contents.json | 0 .../Assets.xcassets/Contents.json | 0 .../SupportingFiles/EuDgcSchema.swift | 2 +- .../SupportingFiles/Info.plist | 0 .../SupportingFiles/SceneDelegate.swift | 2 +- .../ViewControllers/CertificateViewer.swift | 2 +- .../ViewControllers/Scan.swift | 2 +- .../DGCAVerifierTests.swift | 8 +- .../EHNTests.swift | 2 +- .../Info.plist | 0 .../DGCAVerifierUITests.swift | 6 +- .../Info.plist | 0 .../xcschemes/xcschememanagement.plist | 77 ------------ 46 files changed, 204 insertions(+), 175 deletions(-) rename {PatientScannerDemo.xcodeproj => DGCAVerifier.xcodeproj}/project.pbxproj (88%) rename {PatientScannerDemo.xcodeproj => DGCAVerifier.xcodeproj}/project.xcworkspace/contents.xcworkspacedata (51%) rename {PatientScannerDemo.xcodeproj => DGCAVerifier.xcodeproj}/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {PatientScannerDemo.xcodeproj => DGCAVerifier.xcodeproj}/project.xcworkspace/xcshareddata/swiftpm/Package.resolved (100%) rename {PatientScannerDemo.xcodeproj => DGCAVerifier.xcodeproj}/xcshareddata/IDETemplateMacros.plist (100%) create mode 100644 DGCAVerifier.xcodeproj/xcshareddata/xcschemes/DGCAVerifier.xcscheme rename {PatientScannerDemo => DGCAVerifier}/Components/FullFloatingPanelLayout.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Components/InfoCell.swift (97%) rename {PatientScannerDemo => DGCAVerifier}/Components/RoundedButton.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Components/SelfSizedTableView.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Extensions/Data+Base45.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Extensions/Data+hexString.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Extensions/Date.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Extensions/String+JSON.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Extensions/String.swift (97%) rename {PatientScannerDemo => DGCAVerifier}/Extensions/SwiftCBOR.CBOR.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Models/HCert.swift (99%) rename {PatientScannerDemo => DGCAVerifier}/Protocols/ChildDismissedDelegate.swift (97%) rename {PatientScannerDemo => DGCAVerifier}/Services/ASN1.swift (100%) rename {PatientScannerDemo => DGCAVerifier}/Services/Base45.swift (100%) rename {PatientScannerDemo => DGCAVerifier}/Services/CBOR.swift (99%) rename {PatientScannerDemo => DGCAVerifier}/Services/COSE.swift (99%) rename {PatientScannerDemo => DGCAVerifier}/Services/JWK.swift (99%) rename {PatientScannerDemo => DGCAVerifier}/Services/KID.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Services/SHA256.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Services/Signature.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Services/X509.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/Services/ZLib.swift (100%) rename {PatientScannerDemo => DGCAVerifier}/Storyboards/Base.lproj/LaunchScreen.storyboard (58%) rename {PatientScannerDemo => DGCAVerifier}/Storyboards/Base.lproj/Main.storyboard (93%) rename {PatientScannerDemo => DGCAVerifier}/Storyboards/CertificateViewer.storyboard (100%) rename {PatientScannerDemo => DGCAVerifier}/SupportingFiles/AppDelegate.swift (98%) rename {PatientScannerDemo => DGCAVerifier}/SupportingFiles/Assets.xcassets/AccentColor.colorset/Contents.json (100%) rename {PatientScannerDemo => DGCAVerifier}/SupportingFiles/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename {PatientScannerDemo => DGCAVerifier}/SupportingFiles/Assets.xcassets/Contents.json (100%) rename {PatientScannerDemo => DGCAVerifier}/SupportingFiles/EuDgcSchema.swift (99%) rename {PatientScannerDemo => DGCAVerifier}/SupportingFiles/Info.plist (100%) rename {PatientScannerDemo => DGCAVerifier}/SupportingFiles/SceneDelegate.swift (97%) rename {PatientScannerDemo => DGCAVerifier}/ViewControllers/CertificateViewer.swift (99%) rename {PatientScannerDemo => DGCAVerifier}/ViewControllers/Scan.swift (99%) rename PatientScannerDemoTests/PatientScannerDemoTests.swift => DGCAVerifierTests/DGCAVerifierTests.swift (84%) rename {PatientScannerDemoTests => DGCAVerifierTests}/EHNTests.swift (99%) rename {PatientScannerDemoTests => DGCAVerifierTests}/Info.plist (100%) rename PatientScannerDemoUITests/PatientScannerDemoUITests.swift => DGCAVerifierUITests/DGCAVerifierUITests.swift (92%) rename {PatientScannerDemoUITests => DGCAVerifierUITests}/Info.plist (100%) delete mode 100644 PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/PatientScannerDemo.xcodeproj/project.pbxproj b/DGCAVerifier.xcodeproj/project.pbxproj similarity index 88% rename from PatientScannerDemo.xcodeproj/project.pbxproj rename to DGCAVerifier.xcodeproj/project.pbxproj index e5b7c70..27b1638 100644 --- a/PatientScannerDemo.xcodeproj/project.pbxproj +++ b/DGCAVerifier.xcodeproj/project.pbxproj @@ -35,8 +35,8 @@ CEA6D6F3261F8D2700715333 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F1261F8D2700715333 /* Main.storyboard */; }; CEA6D6F5261F8D2900715333 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F4261F8D2900715333 /* Assets.xcassets */; }; CEA6D6F8261F8D2900715333 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */; }; - CEA6D703261F8D2900715333 /* PatientScannerDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */; }; - CEA6D70E261F8D2900715333 /* PatientScannerDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */; }; + CEA6D703261F8D2900715333 /* DGCAVerifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D702261F8D2900715333 /* DGCAVerifierTests.swift */; }; + CEA6D70E261F8D2900715333 /* DGCAVerifierUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D70D261F8D2900715333 /* DGCAVerifierUITests.swift */; }; CEC2C4C22625ED030056E406 /* ZLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4BF2625ED030056E406 /* ZLib.swift */; }; CEC2C4C32625ED030056E406 /* JWK.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4C02625ED030056E406 /* JWK.swift */; }; CEC2C4C42625ED030056E406 /* Base45.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2C4C12625ED030056E406 /* Base45.swift */; }; @@ -83,7 +83,7 @@ CEA15562262F6DAB0024B7AC /* ChildDismissedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChildDismissedDelegate.swift; sourceTree = ""; }; CEA1556A262F784E0024B7AC /* SelfSizedTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelfSizedTableView.swift; sourceTree = ""; }; CEA1556F262F79DE0024B7AC /* InfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoCell.swift; sourceTree = ""; }; - CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PatientScannerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + CEA6D6E8261F8D2700715333 /* DGCAVerifier.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DGCAVerifier.app; sourceTree = BUILT_PRODUCTS_DIR; }; CEA6D6EB261F8D2700715333 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; CEA6D6EF261F8D2700715333 /* Scan.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scan.swift; sourceTree = ""; }; @@ -91,11 +91,11 @@ CEA6D6F4261F8D2900715333 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; CEA6D6F7261F8D2900715333 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; CEA6D6F9261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - CEA6D6FE261F8D2900715333 /* PatientScannerDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PatientScannerDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatientScannerDemoTests.swift; sourceTree = ""; }; + CEA6D6FE261F8D2900715333 /* DGCAVerifierTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DGCAVerifierTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + CEA6D702261F8D2900715333 /* DGCAVerifierTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DGCAVerifierTests.swift; sourceTree = ""; }; CEA6D704261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - CEA6D709261F8D2900715333 /* PatientScannerDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PatientScannerDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatientScannerDemoUITests.swift; sourceTree = ""; }; + CEA6D709261F8D2900715333 /* DGCAVerifierUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DGCAVerifierUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + CEA6D70D261F8D2900715333 /* DGCAVerifierUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DGCAVerifierUITests.swift; sourceTree = ""; }; CEA6D70F261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; CEC2C4BF2625ED030056E406 /* ZLib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZLib.swift; sourceTree = ""; }; CEC2C4C02625ED030056E406 /* JWK.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JWK.swift; sourceTree = ""; }; @@ -227,9 +227,9 @@ CEA6D6DF261F8D2700715333 = { isa = PBXGroup; children = ( - CEA6D6EA261F8D2700715333 /* PatientScannerDemo */, - CEA6D701261F8D2900715333 /* PatientScannerDemoTests */, - CEA6D70C261F8D2900715333 /* PatientScannerDemoUITests */, + CEA6D6EA261F8D2700715333 /* DGCAVerifier */, + CEA6D701261F8D2900715333 /* DGCAVerifierTests */, + CEA6D70C261F8D2900715333 /* DGCAVerifierUITests */, CEA6D6E9261F8D2700715333 /* Products */, ); sourceTree = ""; @@ -237,14 +237,14 @@ CEA6D6E9261F8D2700715333 /* Products */ = { isa = PBXGroup; children = ( - CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */, - CEA6D6FE261F8D2900715333 /* PatientScannerDemoTests.xctest */, - CEA6D709261F8D2900715333 /* PatientScannerDemoUITests.xctest */, + CEA6D6E8261F8D2700715333 /* DGCAVerifier.app */, + CEA6D6FE261F8D2900715333 /* DGCAVerifierTests.xctest */, + CEA6D709261F8D2900715333 /* DGCAVerifierUITests.xctest */, ); name = Products; sourceTree = ""; }; - CEA6D6EA261F8D2700715333 /* PatientScannerDemo */ = { + CEA6D6EA261F8D2700715333 /* DGCAVerifier */ = { isa = PBXGroup; children = ( CEA15561262F6DA10024B7AC /* Protocols */, @@ -256,34 +256,34 @@ CE13CF1A262DDE330070C80E /* Services */, CE13CF19262DDE200070C80E /* Storyboards */, ); - path = PatientScannerDemo; + path = DGCAVerifier; sourceTree = ""; }; - CEA6D701261F8D2900715333 /* PatientScannerDemoTests */ = { + CEA6D701261F8D2900715333 /* DGCAVerifierTests */ = { isa = PBXGroup; children = ( - CEA6D702261F8D2900715333 /* PatientScannerDemoTests.swift */, + CEA6D702261F8D2900715333 /* DGCAVerifierTests.swift */, CEA6D704261F8D2900715333 /* Info.plist */, CEFAD87E262714C4009AFEF9 /* EHNTests.swift */, ); - path = PatientScannerDemoTests; + path = DGCAVerifierTests; sourceTree = ""; }; - CEA6D70C261F8D2900715333 /* PatientScannerDemoUITests */ = { + CEA6D70C261F8D2900715333 /* DGCAVerifierUITests */ = { isa = PBXGroup; children = ( - CEA6D70D261F8D2900715333 /* PatientScannerDemoUITests.swift */, + CEA6D70D261F8D2900715333 /* DGCAVerifierUITests.swift */, CEA6D70F261F8D2900715333 /* Info.plist */, ); - path = PatientScannerDemoUITests; + path = DGCAVerifierUITests; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - CEA6D6E7261F8D2700715333 /* PatientScannerDemo */ = { + CEA6D6E7261F8D2700715333 /* DGCAVerifier */ = { isa = PBXNativeTarget; - buildConfigurationList = CEA6D712261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemo" */; + buildConfigurationList = CEA6D712261F8D2900715333 /* Build configuration list for PBXNativeTarget "DGCAVerifier" */; buildPhases = ( CEA6D6E4261F8D2700715333 /* Sources */, CEA6D6E5261F8D2700715333 /* Frameworks */, @@ -293,7 +293,7 @@ ); dependencies = ( ); - name = PatientScannerDemo; + name = DGCAVerifier; packageProductDependencies = ( CE7DE7F92625EF18007E6694 /* SwiftCBOR */, CE13CEFF262DCC180070C80E /* FloatingPanel */, @@ -301,12 +301,12 @@ CE44798C26304D8F009A836B /* JSONSchema */, ); productName = PatientScannerDemo; - productReference = CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */; + productReference = CEA6D6E8261F8D2700715333 /* DGCAVerifier.app */; productType = "com.apple.product-type.application"; }; - CEA6D6FD261F8D2900715333 /* PatientScannerDemoTests */ = { + CEA6D6FD261F8D2900715333 /* DGCAVerifierTests */ = { isa = PBXNativeTarget; - buildConfigurationList = CEA6D715261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemoTests" */; + buildConfigurationList = CEA6D715261F8D2900715333 /* Build configuration list for PBXNativeTarget "DGCAVerifierTests" */; buildPhases = ( CEA6D6FA261F8D2900715333 /* Sources */, CEA6D6FB261F8D2900715333 /* Frameworks */, @@ -317,14 +317,14 @@ dependencies = ( CEA6D700261F8D2900715333 /* PBXTargetDependency */, ); - name = PatientScannerDemoTests; + name = DGCAVerifierTests; productName = PatientScannerDemoTests; - productReference = CEA6D6FE261F8D2900715333 /* PatientScannerDemoTests.xctest */; + productReference = CEA6D6FE261F8D2900715333 /* DGCAVerifierTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - CEA6D708261F8D2900715333 /* PatientScannerDemoUITests */ = { + CEA6D708261F8D2900715333 /* DGCAVerifierUITests */ = { isa = PBXNativeTarget; - buildConfigurationList = CEA6D718261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemoUITests" */; + buildConfigurationList = CEA6D718261F8D2900715333 /* Build configuration list for PBXNativeTarget "DGCAVerifierUITests" */; buildPhases = ( CEA6D705261F8D2900715333 /* Sources */, CEA6D706261F8D2900715333 /* Frameworks */, @@ -335,9 +335,9 @@ dependencies = ( CEA6D70B261F8D2900715333 /* PBXTargetDependency */, ); - name = PatientScannerDemoUITests; + name = DGCAVerifierUITests; productName = PatientScannerDemoUITests; - productReference = CEA6D709261F8D2900715333 /* PatientScannerDemoUITests.xctest */; + productReference = CEA6D709261F8D2900715333 /* DGCAVerifierUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; /* End PBXNativeTarget section */ @@ -362,7 +362,7 @@ }; }; }; - buildConfigurationList = CEA6D6E3261F8D2700715333 /* Build configuration list for PBXProject "PatientScannerDemo" */; + buildConfigurationList = CEA6D6E3261F8D2700715333 /* Build configuration list for PBXProject "DGCAVerifier" */; compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; @@ -381,9 +381,9 @@ projectDirPath = ""; projectRoot = ""; targets = ( - CEA6D6E7261F8D2700715333 /* PatientScannerDemo */, - CEA6D6FD261F8D2900715333 /* PatientScannerDemoTests */, - CEA6D708261F8D2900715333 /* PatientScannerDemoUITests */, + CEA6D6E7261F8D2700715333 /* DGCAVerifier */, + CEA6D6FD261F8D2900715333 /* DGCAVerifierTests */, + CEA6D708261F8D2900715333 /* DGCAVerifierUITests */, ); }; /* End PBXProject section */ @@ -455,7 +455,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - CEA6D703261F8D2900715333 /* PatientScannerDemoTests.swift in Sources */, + CEA6D703261F8D2900715333 /* DGCAVerifierTests.swift in Sources */, CEFAD87F262714C4009AFEF9 /* EHNTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -464,7 +464,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - CEA6D70E261F8D2900715333 /* PatientScannerDemoUITests.swift in Sources */, + CEA6D70E261F8D2900715333 /* DGCAVerifierUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -473,12 +473,12 @@ /* Begin PBXTargetDependency section */ CEA6D700261F8D2900715333 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = CEA6D6E7261F8D2700715333 /* PatientScannerDemo */; + target = CEA6D6E7261F8D2700715333 /* DGCAVerifier */; targetProxy = CEA6D6FF261F8D2900715333 /* PBXContainerItemProxy */; }; CEA6D70B261F8D2900715333 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = CEA6D6E7261F8D2700715333 /* PatientScannerDemo */; + target = CEA6D6E7261F8D2700715333 /* DGCAVerifier */; targetProxy = CEA6D70A261F8D2900715333 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -626,13 +626,13 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemo/SupportingFiles/Info.plist; + INFOPLIST_FILE = DGCAVerifier/SupportingFiles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemo"; + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.DGCAVerifier.dev"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -646,13 +646,13 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemo/SupportingFiles/Info.plist; + INFOPLIST_FILE = DGCAVerifier/SupportingFiles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemo"; + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.DGCAVerifier.dev"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -666,18 +666,18 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemo/SupportingFiles/Info.plist; + INFOPLIST_FILE = DGCAVerifier/SupportingFiles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemoTests"; + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.DGCAVerifierTests.dev"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PatientScannerDemo.app/PatientScannerDemo"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DGCAVerifier.app/DGCAVerifier"; }; name = Debug; }; @@ -688,18 +688,18 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemo/SupportingFiles/Info.plist; + INFOPLIST_FILE = DGCAVerifier/SupportingFiles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemoTests"; + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.DGCAVerifierTests.dev"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PatientScannerDemo.app/PatientScannerDemo"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DGCAVerifier.app/DGCAVerifier"; }; name = Release; }; @@ -709,13 +709,13 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemoUITests/Info.plist; + INFOPLIST_FILE = DGCAVerifierUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemoUITests"; + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.DGCAVerifierUITests.dev"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -729,13 +729,13 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = KH99XNF745; - INFOPLIST_FILE = PatientScannerDemoUITests/Info.plist; + INFOPLIST_FILE = DGCAVerifierUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.PatientScannerDemoUITests"; + PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.DGCAVerifierUITests.dev"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -746,7 +746,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - CEA6D6E3261F8D2700715333 /* Build configuration list for PBXProject "PatientScannerDemo" */ = { + CEA6D6E3261F8D2700715333 /* Build configuration list for PBXProject "DGCAVerifier" */ = { isa = XCConfigurationList; buildConfigurations = ( CEA6D710261F8D2900715333 /* Debug */, @@ -755,7 +755,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - CEA6D712261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemo" */ = { + CEA6D712261F8D2900715333 /* Build configuration list for PBXNativeTarget "DGCAVerifier" */ = { isa = XCConfigurationList; buildConfigurations = ( CEA6D713261F8D2900715333 /* Debug */, @@ -764,7 +764,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - CEA6D715261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemoTests" */ = { + CEA6D715261F8D2900715333 /* Build configuration list for PBXNativeTarget "DGCAVerifierTests" */ = { isa = XCConfigurationList; buildConfigurations = ( CEA6D716261F8D2900715333 /* Debug */, @@ -773,7 +773,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - CEA6D718261F8D2900715333 /* Build configuration list for PBXNativeTarget "PatientScannerDemoUITests" */ = { + CEA6D718261F8D2900715333 /* Build configuration list for PBXNativeTarget "DGCAVerifierUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( CEA6D719261F8D2900715333 /* Debug */, diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DGCAVerifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 51% rename from PatientScannerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to DGCAVerifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 919434a..50c8523 100644 --- a/PatientScannerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/DGCAVerifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:/Users/user/Documents/proj/dgc/dgca-verifier-app-ios/DGCAVerifier.xcodeproj"> diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DGCAVerifier.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to DGCAVerifier.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DGCAVerifier.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved similarity index 100% rename from PatientScannerDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved rename to DGCAVerifier.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist b/DGCAVerifier.xcodeproj/xcshareddata/IDETemplateMacros.plist similarity index 100% rename from PatientScannerDemo.xcodeproj/xcshareddata/IDETemplateMacros.plist rename to DGCAVerifier.xcodeproj/xcshareddata/IDETemplateMacros.plist diff --git a/DGCAVerifier.xcodeproj/xcshareddata/xcschemes/DGCAVerifier.xcscheme b/DGCAVerifier.xcodeproj/xcshareddata/xcschemes/DGCAVerifier.xcscheme new file mode 100644 index 0000000..622ac34 --- /dev/null +++ b/DGCAVerifier.xcodeproj/xcshareddata/xcschemes/DGCAVerifier.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PatientScannerDemo/Components/FullFloatingPanelLayout.swift b/DGCAVerifier/Components/FullFloatingPanelLayout.swift similarity index 98% rename from PatientScannerDemo/Components/FullFloatingPanelLayout.swift rename to DGCAVerifier/Components/FullFloatingPanelLayout.swift index 205e4b9..1dcba94 100644 --- a/PatientScannerDemo/Components/FullFloatingPanelLayout.swift +++ b/DGCAVerifier/Components/FullFloatingPanelLayout.swift @@ -19,7 +19,7 @@ */ // // FullFloatingPanelLayout.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/19/21. // diff --git a/PatientScannerDemo/Components/InfoCell.swift b/DGCAVerifier/Components/InfoCell.swift similarity index 97% rename from PatientScannerDemo/Components/InfoCell.swift rename to DGCAVerifier/Components/InfoCell.swift index fbe680b..6f12a42 100644 --- a/PatientScannerDemo/Components/InfoCell.swift +++ b/DGCAVerifier/Components/InfoCell.swift @@ -19,7 +19,7 @@ */ // // InfoCell.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/20/21. // diff --git a/PatientScannerDemo/Components/RoundedButton.swift b/DGCAVerifier/Components/RoundedButton.swift similarity index 98% rename from PatientScannerDemo/Components/RoundedButton.swift rename to DGCAVerifier/Components/RoundedButton.swift index c928291..bacf12f 100644 --- a/PatientScannerDemo/Components/RoundedButton.swift +++ b/DGCAVerifier/Components/RoundedButton.swift @@ -19,7 +19,7 @@ */ // // RoundedButton.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/19/21. // diff --git a/PatientScannerDemo/Components/SelfSizedTableView.swift b/DGCAVerifier/Components/SelfSizedTableView.swift similarity index 98% rename from PatientScannerDemo/Components/SelfSizedTableView.swift rename to DGCAVerifier/Components/SelfSizedTableView.swift index a69ea86..1c4062e 100644 --- a/PatientScannerDemo/Components/SelfSizedTableView.swift +++ b/DGCAVerifier/Components/SelfSizedTableView.swift @@ -19,7 +19,7 @@ */ // // SelfSizedTableView.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/20/21. // diff --git a/PatientScannerDemo/Extensions/Data+Base45.swift b/DGCAVerifier/Extensions/Data+Base45.swift similarity index 98% rename from PatientScannerDemo/Extensions/Data+Base45.swift rename to DGCAVerifier/Extensions/Data+Base45.swift index 7eb0322..841414b 100644 --- a/PatientScannerDemo/Extensions/Data+Base45.swift +++ b/DGCAVerifier/Extensions/Data+Base45.swift @@ -19,7 +19,7 @@ */ // // Data+Base45.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/21/21. // diff --git a/PatientScannerDemo/Extensions/Data+hexString.swift b/DGCAVerifier/Extensions/Data+hexString.swift similarity index 98% rename from PatientScannerDemo/Extensions/Data+hexString.swift rename to DGCAVerifier/Extensions/Data+hexString.swift index 9914aa4..0ce6b58 100644 --- a/PatientScannerDemo/Extensions/Data+hexString.swift +++ b/DGCAVerifier/Extensions/Data+hexString.swift @@ -19,7 +19,7 @@ */ // // Data+hexString.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/14/21. // diff --git a/PatientScannerDemo/Extensions/Date.swift b/DGCAVerifier/Extensions/Date.swift similarity index 98% rename from PatientScannerDemo/Extensions/Date.swift rename to DGCAVerifier/Extensions/Date.swift index 19e8687..18a34e2 100644 --- a/PatientScannerDemo/Extensions/Date.swift +++ b/DGCAVerifier/Extensions/Date.swift @@ -19,7 +19,7 @@ */ // // Date.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/19/21. // diff --git a/PatientScannerDemo/Extensions/String+JSON.swift b/DGCAVerifier/Extensions/String+JSON.swift similarity index 98% rename from PatientScannerDemo/Extensions/String+JSON.swift rename to DGCAVerifier/Extensions/String+JSON.swift index d8f495a..c7958d4 100644 --- a/PatientScannerDemo/Extensions/String+JSON.swift +++ b/DGCAVerifier/Extensions/String+JSON.swift @@ -19,7 +19,7 @@ */ // // File.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/13/21. // diff --git a/PatientScannerDemo/Extensions/String.swift b/DGCAVerifier/Extensions/String.swift similarity index 97% rename from PatientScannerDemo/Extensions/String.swift rename to DGCAVerifier/Extensions/String.swift index 928027d..e885178 100644 --- a/PatientScannerDemo/Extensions/String.swift +++ b/DGCAVerifier/Extensions/String.swift @@ -19,7 +19,7 @@ */ // // String.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/21/21. // diff --git a/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift b/DGCAVerifier/Extensions/SwiftCBOR.CBOR.swift similarity index 98% rename from PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift rename to DGCAVerifier/Extensions/SwiftCBOR.CBOR.swift index 607ba0f..d8bb7eb 100644 --- a/PatientScannerDemo/Extensions/SwiftCBOR.CBOR.swift +++ b/DGCAVerifier/Extensions/SwiftCBOR.CBOR.swift @@ -19,7 +19,7 @@ */ // // SwiftCBOR.CBOR.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/19/21. // diff --git a/PatientScannerDemo/Models/HCert.swift b/DGCAVerifier/Models/HCert.swift similarity index 99% rename from PatientScannerDemo/Models/HCert.swift rename to DGCAVerifier/Models/HCert.swift index 20ecd7a..4055b25 100644 --- a/PatientScannerDemo/Models/HCert.swift +++ b/DGCAVerifier/Models/HCert.swift @@ -19,7 +19,7 @@ */ // // HCert.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/19/21. // diff --git a/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift b/DGCAVerifier/Protocols/ChildDismissedDelegate.swift similarity index 97% rename from PatientScannerDemo/Protocols/ChildDismissedDelegate.swift rename to DGCAVerifier/Protocols/ChildDismissedDelegate.swift index 076d8d6..735cf0a 100644 --- a/PatientScannerDemo/Protocols/ChildDismissedDelegate.swift +++ b/DGCAVerifier/Protocols/ChildDismissedDelegate.swift @@ -19,7 +19,7 @@ */ // // ChildDismissedDelegate.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/20/21. // diff --git a/PatientScannerDemo/Services/ASN1.swift b/DGCAVerifier/Services/ASN1.swift similarity index 100% rename from PatientScannerDemo/Services/ASN1.swift rename to DGCAVerifier/Services/ASN1.swift diff --git a/PatientScannerDemo/Services/Base45.swift b/DGCAVerifier/Services/Base45.swift similarity index 100% rename from PatientScannerDemo/Services/Base45.swift rename to DGCAVerifier/Services/Base45.swift diff --git a/PatientScannerDemo/Services/CBOR.swift b/DGCAVerifier/Services/CBOR.swift similarity index 99% rename from PatientScannerDemo/Services/CBOR.swift rename to DGCAVerifier/Services/CBOR.swift index 0e0c8af..abaa876 100644 --- a/PatientScannerDemo/Services/CBOR.swift +++ b/DGCAVerifier/Services/CBOR.swift @@ -19,7 +19,7 @@ */ // // CBOR.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/15/21. // diff --git a/PatientScannerDemo/Services/COSE.swift b/DGCAVerifier/Services/COSE.swift similarity index 99% rename from PatientScannerDemo/Services/COSE.swift rename to DGCAVerifier/Services/COSE.swift index a7e8098..498c352 100644 --- a/PatientScannerDemo/Services/COSE.swift +++ b/DGCAVerifier/Services/COSE.swift @@ -19,7 +19,7 @@ */ // // COSE.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/14/21. // diff --git a/PatientScannerDemo/Services/JWK.swift b/DGCAVerifier/Services/JWK.swift similarity index 99% rename from PatientScannerDemo/Services/JWK.swift rename to DGCAVerifier/Services/JWK.swift index cd36a4c..9f1cc7c 100644 --- a/PatientScannerDemo/Services/JWK.swift +++ b/DGCAVerifier/Services/JWK.swift @@ -19,7 +19,7 @@ */ // // JWK.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/13/21. // diff --git a/PatientScannerDemo/Services/KID.swift b/DGCAVerifier/Services/KID.swift similarity index 98% rename from PatientScannerDemo/Services/KID.swift rename to DGCAVerifier/Services/KID.swift index 8d36807..905d62d 100644 --- a/PatientScannerDemo/Services/KID.swift +++ b/DGCAVerifier/Services/KID.swift @@ -20,7 +20,7 @@ */ // // KID.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/22/21. // diff --git a/PatientScannerDemo/Services/SHA256.swift b/DGCAVerifier/Services/SHA256.swift similarity index 98% rename from PatientScannerDemo/Services/SHA256.swift rename to DGCAVerifier/Services/SHA256.swift index 57fb5f8..62fd682 100644 --- a/PatientScannerDemo/Services/SHA256.swift +++ b/DGCAVerifier/Services/SHA256.swift @@ -20,7 +20,7 @@ */ // // SHA256.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/22/21. // diff --git a/PatientScannerDemo/Services/Signature.swift b/DGCAVerifier/Services/Signature.swift similarity index 98% rename from PatientScannerDemo/Services/Signature.swift rename to DGCAVerifier/Services/Signature.swift index c1f6737..27465e2 100644 --- a/PatientScannerDemo/Services/Signature.swift +++ b/DGCAVerifier/Services/Signature.swift @@ -19,7 +19,7 @@ */ // // EC256.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/13/21. // diff --git a/PatientScannerDemo/Services/X509.swift b/DGCAVerifier/Services/X509.swift similarity index 98% rename from PatientScannerDemo/Services/X509.swift rename to DGCAVerifier/Services/X509.swift index 1d482bc..744d665 100644 --- a/PatientScannerDemo/Services/X509.swift +++ b/DGCAVerifier/Services/X509.swift @@ -19,7 +19,7 @@ */ // // X509.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/17/21. // diff --git a/PatientScannerDemo/Services/ZLib.swift b/DGCAVerifier/Services/ZLib.swift similarity index 100% rename from PatientScannerDemo/Services/ZLib.swift rename to DGCAVerifier/Services/ZLib.swift diff --git a/PatientScannerDemo/Storyboards/Base.lproj/LaunchScreen.storyboard b/DGCAVerifier/Storyboards/Base.lproj/LaunchScreen.storyboard similarity index 58% rename from PatientScannerDemo/Storyboards/Base.lproj/LaunchScreen.storyboard rename to DGCAVerifier/Storyboards/Base.lproj/LaunchScreen.storyboard index 865e932..0b64f64 100644 --- a/PatientScannerDemo/Storyboards/Base.lproj/LaunchScreen.storyboard +++ b/DGCAVerifier/Storyboards/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,11 @@ - - + + + - + + + @@ -11,10 +14,10 @@ - + - + @@ -22,4 +25,9 @@ + + + + + diff --git a/PatientScannerDemo/Storyboards/Base.lproj/Main.storyboard b/DGCAVerifier/Storyboards/Base.lproj/Main.storyboard similarity index 93% rename from PatientScannerDemo/Storyboards/Base.lproj/Main.storyboard rename to DGCAVerifier/Storyboards/Base.lproj/Main.storyboard index 0c8a017..71e66d0 100644 --- a/PatientScannerDemo/Storyboards/Base.lproj/Main.storyboard +++ b/DGCAVerifier/Storyboards/Base.lproj/Main.storyboard @@ -11,7 +11,7 @@ - + diff --git a/PatientScannerDemo/Storyboards/CertificateViewer.storyboard b/DGCAVerifier/Storyboards/CertificateViewer.storyboard similarity index 100% rename from PatientScannerDemo/Storyboards/CertificateViewer.storyboard rename to DGCAVerifier/Storyboards/CertificateViewer.storyboard diff --git a/PatientScannerDemo/SupportingFiles/AppDelegate.swift b/DGCAVerifier/SupportingFiles/AppDelegate.swift similarity index 98% rename from PatientScannerDemo/SupportingFiles/AppDelegate.swift rename to DGCAVerifier/SupportingFiles/AppDelegate.swift index 9272256..5ea636f 100644 --- a/PatientScannerDemo/SupportingFiles/AppDelegate.swift +++ b/DGCAVerifier/SupportingFiles/AppDelegate.swift @@ -19,7 +19,7 @@ */ // // AppDelegate.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/8/21. // diff --git a/PatientScannerDemo/SupportingFiles/Assets.xcassets/AccentColor.colorset/Contents.json b/DGCAVerifier/SupportingFiles/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from PatientScannerDemo/SupportingFiles/Assets.xcassets/AccentColor.colorset/Contents.json rename to DGCAVerifier/SupportingFiles/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/PatientScannerDemo/SupportingFiles/Assets.xcassets/AppIcon.appiconset/Contents.json b/DGCAVerifier/SupportingFiles/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from PatientScannerDemo/SupportingFiles/Assets.xcassets/AppIcon.appiconset/Contents.json rename to DGCAVerifier/SupportingFiles/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/PatientScannerDemo/SupportingFiles/Assets.xcassets/Contents.json b/DGCAVerifier/SupportingFiles/Assets.xcassets/Contents.json similarity index 100% rename from PatientScannerDemo/SupportingFiles/Assets.xcassets/Contents.json rename to DGCAVerifier/SupportingFiles/Assets.xcassets/Contents.json diff --git a/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift b/DGCAVerifier/SupportingFiles/EuDgcSchema.swift similarity index 99% rename from PatientScannerDemo/SupportingFiles/EuDgcSchema.swift rename to DGCAVerifier/SupportingFiles/EuDgcSchema.swift index bd43548..579ecbe 100644 --- a/PatientScannerDemo/SupportingFiles/EuDgcSchema.swift +++ b/DGCAVerifier/SupportingFiles/EuDgcSchema.swift @@ -19,7 +19,7 @@ */ // // EuDgcSchema.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/20/21. // diff --git a/PatientScannerDemo/SupportingFiles/Info.plist b/DGCAVerifier/SupportingFiles/Info.plist similarity index 100% rename from PatientScannerDemo/SupportingFiles/Info.plist rename to DGCAVerifier/SupportingFiles/Info.plist diff --git a/PatientScannerDemo/SupportingFiles/SceneDelegate.swift b/DGCAVerifier/SupportingFiles/SceneDelegate.swift similarity index 97% rename from PatientScannerDemo/SupportingFiles/SceneDelegate.swift rename to DGCAVerifier/SupportingFiles/SceneDelegate.swift index e561605..6174aa5 100644 --- a/PatientScannerDemo/SupportingFiles/SceneDelegate.swift +++ b/DGCAVerifier/SupportingFiles/SceneDelegate.swift @@ -19,7 +19,7 @@ */ // // SceneDelegate.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/8/21. // diff --git a/PatientScannerDemo/ViewControllers/CertificateViewer.swift b/DGCAVerifier/ViewControllers/CertificateViewer.swift similarity index 99% rename from PatientScannerDemo/ViewControllers/CertificateViewer.swift rename to DGCAVerifier/ViewControllers/CertificateViewer.swift index 4c202af..466e5ee 100644 --- a/PatientScannerDemo/ViewControllers/CertificateViewer.swift +++ b/DGCAVerifier/ViewControllers/CertificateViewer.swift @@ -19,7 +19,7 @@ */ // // CertificateViewer.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/19/21. // diff --git a/PatientScannerDemo/ViewControllers/Scan.swift b/DGCAVerifier/ViewControllers/Scan.swift similarity index 99% rename from PatientScannerDemo/ViewControllers/Scan.swift rename to DGCAVerifier/ViewControllers/Scan.swift index 49a3464..ecc7ad7 100644 --- a/PatientScannerDemo/ViewControllers/Scan.swift +++ b/DGCAVerifier/ViewControllers/Scan.swift @@ -19,7 +19,7 @@ */ // // ViewController.swift -// PatientScannerDemo +// DGCAVerifier // // Created by Yannick Spreen on 4/8/21. // diff --git a/PatientScannerDemoTests/PatientScannerDemoTests.swift b/DGCAVerifierTests/DGCAVerifierTests.swift similarity index 84% rename from PatientScannerDemoTests/PatientScannerDemoTests.swift rename to DGCAVerifierTests/DGCAVerifierTests.swift index 11b58a1..84fd71e 100644 --- a/PatientScannerDemoTests/PatientScannerDemoTests.swift +++ b/DGCAVerifierTests/DGCAVerifierTests.swift @@ -1,14 +1,14 @@ // -// PatientScannerDemoTests.swift -// PatientScannerDemoTests +// DGCAVerifierTests.swift +// DGCAVerifierTests // // Created by Yannick Spreen on 4/8/21. // import XCTest -@testable import PatientScannerDemo +@testable import DGCAVerifier -class PatientScannerDemoTests: XCTestCase { +class DGCAVerifierTests: XCTestCase { override func setUpWithError() throws { // Put setup code here. This method is called before the invocation of each test method in the class. diff --git a/PatientScannerDemoTests/EHNTests.swift b/DGCAVerifierTests/EHNTests.swift similarity index 99% rename from PatientScannerDemoTests/EHNTests.swift rename to DGCAVerifierTests/EHNTests.swift index 7fbac13..79675ed 100644 --- a/PatientScannerDemoTests/EHNTests.swift +++ b/DGCAVerifierTests/EHNTests.swift @@ -5,7 +5,7 @@ // Created by Dirk-Willem van Gulik on 01/04/2021. // -@testable import PatientScannerDemo +@testable import DGCAVerifier import XCTest class EHNTests: XCTestCase { diff --git a/PatientScannerDemoTests/Info.plist b/DGCAVerifierTests/Info.plist similarity index 100% rename from PatientScannerDemoTests/Info.plist rename to DGCAVerifierTests/Info.plist diff --git a/PatientScannerDemoUITests/PatientScannerDemoUITests.swift b/DGCAVerifierUITests/DGCAVerifierUITests.swift similarity index 92% rename from PatientScannerDemoUITests/PatientScannerDemoUITests.swift rename to DGCAVerifierUITests/DGCAVerifierUITests.swift index 2dadbd5..6703018 100644 --- a/PatientScannerDemoUITests/PatientScannerDemoUITests.swift +++ b/DGCAVerifierUITests/DGCAVerifierUITests.swift @@ -1,13 +1,13 @@ // -// PatientScannerDemoUITests.swift -// PatientScannerDemoUITests +// DGCAVerifierUITests.swift +// DGCAVerifierUITests // // Created by Yannick Spreen on 4/8/21. // import XCTest -class PatientScannerDemoUITests: XCTestCase { +class DGCAVerifierUITests: XCTestCase { override func setUpWithError() throws { // Put setup code here. This method is called before the invocation of each test method in the class. diff --git a/PatientScannerDemoUITests/Info.plist b/DGCAVerifierUITests/Info.plist similarity index 100% rename from PatientScannerDemoUITests/Info.plist rename to DGCAVerifierUITests/Info.plist diff --git a/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist b/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 1e971f7..0000000 --- a/PatientScannerDemo.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,77 +0,0 @@ - - - - - SchemeUserState - - PatientScannerDemo.xcscheme_^#shared#^_ - - orderHint - 0 - - Playground (Playground) 1.xcscheme - - isShown - - orderHint - 5 - - Playground (Playground) 2.xcscheme - - isShown - - orderHint - 6 - - Playground (Playground).xcscheme - - isShown - - orderHint - 4 - - Spectre (Playground) 1.xcscheme - - isShown - - orderHint - 2 - - Spectre (Playground) 2.xcscheme - - isShown - - orderHint - 3 - - Spectre (Playground) 3.xcscheme - - isShown - - orderHint - 7 - - Spectre (Playground) 4.xcscheme - - isShown - - orderHint - 8 - - Spectre (Playground) 5.xcscheme - - isShown - - orderHint - 9 - - Spectre (Playground).xcscheme - - isShown - - orderHint - 1 - - - - From 23ae178c7a97b6eb82f3b8096a5827c6a1a34c88 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Sun, 25 Apr 2021 14:11:21 +0200 Subject: [PATCH 62/89] Replace old name completely. --- DGCAVerifier.xcodeproj/project.pbxproj | 14 +++++------ .../contents.xcworkspacedata | 2 +- .../Storyboards/CertificateViewer.storyboard | 24 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/DGCAVerifier.xcodeproj/project.pbxproj b/DGCAVerifier.xcodeproj/project.pbxproj index 27b1638..d332b17 100644 --- a/DGCAVerifier.xcodeproj/project.pbxproj +++ b/DGCAVerifier.xcodeproj/project.pbxproj @@ -53,14 +53,14 @@ containerPortal = CEA6D6E0261F8D2700715333 /* Project object */; proxyType = 1; remoteGlobalIDString = CEA6D6E7261F8D2700715333; - remoteInfo = PatientScannerDemo; + remoteInfo = DGCAVerifier; }; CEA6D70A261F8D2900715333 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = CEA6D6E0261F8D2700715333 /* Project object */; proxyType = 1; remoteGlobalIDString = CEA6D6E7261F8D2700715333; - remoteInfo = PatientScannerDemo; + remoteInfo = DGCAVerifier; }; /* End PBXContainerItemProxy section */ @@ -300,7 +300,7 @@ CE157F86262E24DE00FE4821 /* SwiftyJSON */, CE44798C26304D8F009A836B /* JSONSchema */, ); - productName = PatientScannerDemo; + productName = DGCAVerifier; productReference = CEA6D6E8261F8D2700715333 /* DGCAVerifier.app */; productType = "com.apple.product-type.application"; }; @@ -318,7 +318,7 @@ CEA6D700261F8D2900715333 /* PBXTargetDependency */, ); name = DGCAVerifierTests; - productName = PatientScannerDemoTests; + productName = DGCAVerifierTests; productReference = CEA6D6FE261F8D2900715333 /* DGCAVerifierTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; @@ -336,7 +336,7 @@ CEA6D70B261F8D2900715333 /* PBXTargetDependency */, ); name = DGCAVerifierUITests; - productName = PatientScannerDemoUITests; + productName = DGCAVerifierUITests; productReference = CEA6D709261F8D2900715333 /* DGCAVerifierUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; @@ -719,7 +719,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = PatientScannerDemo; + TEST_TARGET_NAME = DGCAVerifier; }; name = Debug; }; @@ -739,7 +739,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = PatientScannerDemo; + TEST_TARGET_NAME = DGCAVerifier; }; name = Release; }; diff --git a/DGCAVerifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DGCAVerifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 50c8523..919434a 100644 --- a/DGCAVerifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/DGCAVerifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/DGCAVerifier/Storyboards/CertificateViewer.storyboard b/DGCAVerifier/Storyboards/CertificateViewer.storyboard index 941cbdb..f258f03 100644 --- a/DGCAVerifier/Storyboards/CertificateViewer.storyboard +++ b/DGCAVerifier/Storyboards/CertificateViewer.storyboard @@ -12,7 +12,7 @@ - + @@ -27,8 +27,8 @@ -