diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4a34fefc1..eff229b88 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -95,8 +95,8 @@ jobs: - name: Set up Homebrew id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master - - name: Install Swift-sh - run: brew install swift-sh + - name: Install Swift-sh and FlatBuffers + run: brew install swift-sh flatbuffers - name: Build and Archive env: APP_PROVISIONING_PROFILE_UUID: ${{ secrets.APP_PROVISIONING_PROFILE_UUID }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8a8abedde..4948dfb52 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -18,6 +18,9 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Install FlatBuffers + run: brew install flatbuffers + # Creating sample files needed to build, but not needed for CodeQL. # .plist files need a sample structure to avoid error: "unable to read input file as a property list" - name: Create sample files diff --git a/CryptoLib/CryptoLib.xcodeproj/project.pbxproj b/CryptoLib/CryptoLib.xcodeproj/project.pbxproj index a391252a7..e973ca688 100644 --- a/CryptoLib/CryptoLib.xcodeproj/project.pbxproj +++ b/CryptoLib/CryptoLib.xcodeproj/project.pbxproj @@ -9,28 +9,22 @@ /* Begin PBXBuildFile section */ 39231FAF20AB1C6C00E1E2B4 /* CryptoLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 39231FAD20AB1C6C00E1E2B4 /* CryptoLib.h */; settings = {ATTRIBUTES = (Public, ); }; }; 39266A5120CFBDF8002E3F23 /* SmartCardTokenWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 39266A5020CFBDF8002E3F23 /* SmartCardTokenWrapper.mm */; }; - 39266A5D20CFDC59002E3F23 /* CdocParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 39266A5C20CFDC59002E3F23 /* CdocParser.m */; }; - 39266A5F20CFDCB9002E3F23 /* CdocInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 39266A5E20CFDCB9002E3F23 /* CdocInfo.m */; }; - 39266A6320CFE3D4002E3F23 /* CdocParserDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 39266A6220CFE3D4002E3F23 /* CdocParserDelegate.m */; }; - 39266A6420CFE63D002E3F23 /* CdocParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 39266A5B20CFDC41002E3F23 /* CdocParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 39266A6520CFE643002E3F23 /* CdocInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 39266A6020CFDCDF002E3F23 /* CdocInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 393B66E020DB94B4001DC89B /* cdoc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 393B66DF20DB94B4001DC89B /* cdoc.framework */; }; - 3960E50520C02E5900D4D2FC /* CryptoDataFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 3960E50420C02E5900D4D2FC /* CryptoDataFile.m */; }; - 3960E50620C044EE00D4D2FC /* CryptoDataFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 3960E50320C02DA400D4D2FC /* CryptoDataFile.h */; settings = {ATTRIBUTES = (Public, ); }; }; 39852A4B20AB2418004CB100 /* Decrypt.h in Headers */ = {isa = PBXBuildFile; fileRef = 39852A4120AB2418004CB100 /* Decrypt.h */; settings = {ATTRIBUTES = (Public, ); }; }; 39852A4C20AB2418004CB100 /* Encrypt.h in Headers */ = {isa = PBXBuildFile; fileRef = 39852A4220AB2418004CB100 /* Encrypt.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 39852A5020AB2418004CB100 /* DdocParserDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 39852A4620AB2418004CB100 /* DdocParserDelegate.m */; }; 39852A5120AB2418004CB100 /* SmartCardTokenWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 39852A4720AB2418004CB100 /* SmartCardTokenWrapper.h */; }; 39852A5220AB2418004CB100 /* Decrypt.mm in Sources */ = {isa = PBXBuildFile; fileRef = 39852A4820AB2418004CB100 /* Decrypt.mm */; }; 39852A5320AB2418004CB100 /* Encrypt.mm in Sources */ = {isa = PBXBuildFile; fileRef = 39852A4920AB2418004CB100 /* Encrypt.mm */; }; - 39852A5420AB2418004CB100 /* DdocParserDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 39852A4A20AB2418004CB100 /* DdocParserDelegate.h */; }; - 39E2B4D920AD7A3400CA74A8 /* Addressee.m in Sources */ = {isa = PBXBuildFile; fileRef = 39E2B4CF20AD7A3400CA74A8 /* Addressee.m */; }; - 39E2B4DF20AD7A3400CA74A8 /* Addressee.h in Headers */ = {isa = PBXBuildFile; fileRef = 39E2B4D520AD7A3400CA74A8 /* Addressee.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4E0454632D3BE73D0013DF23 /* CryptoDataFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E0454622D3BE73D0013DF23 /* CryptoDataFile.swift */; }; + 4E17B8322D6486040063C5BF /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E17B8302D6485750063C5BF /* libz.tbd */; }; 4E17B8352D64A1080063C5BF /* X509CertificateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E17B8342D64A0FD0063C5BF /* X509CertificateType.swift */; }; + 4E276E042D81A61000D78F40 /* Extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E276E032D81A60600D78F40 /* Extensions.h */; }; 4E3681D92D40EAAD00D76DAB /* OpenLdap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3681D72D40EAAD00D76DAB /* OpenLdap.swift */; }; 4E3681DB2D40EAE800D76DAB /* MoppLdapConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3681DA2D40EAE800D76DAB /* MoppLdapConfiguration.swift */; }; 4E8990862D710DC50010CA1F /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E8990852D710DBC0010CA1F /* libxml2.tbd */; }; 4EAC69122D481D1C00A53079 /* ASN1Decoder in Frameworks */ = {isa = PBXBuildFile; productRef = 4EAC69112D481D1C00A53079 /* ASN1Decoder */; }; + 4EB03C7D2D3BE4FB00D5F9AC /* Addressee.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB03C7C2D3BE4FB00D5F9AC /* Addressee.swift */; }; + 4EB03C7F2D3BE6F700D5F9AC /* CdocInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB03C7E2D3BE6F700D5F9AC /* CdocInfo.swift */; }; 4EEE43222D7CF3C9003D0112 /* AbstractSmartToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39266A5920CFD93E002E3F23 /* AbstractSmartToken.swift */; }; DFA40D2F2ADF635F003EF945 /* 3513523f.0 in Resources */ = {isa = PBXBuildFile; fileRef = DFA40D2E2ADF635F003EF945 /* 3513523f.0 */; }; DFC7CA452AE010C9009D85FF /* 9f4c149e.0 in Resources */ = {isa = PBXBuildFile; fileRef = DFC7CA442AE010C9009D85FF /* 9f4c149e.0 */; }; @@ -58,29 +52,22 @@ 39231FAD20AB1C6C00E1E2B4 /* CryptoLib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoLib.h; sourceTree = ""; }; 39266A5020CFBDF8002E3F23 /* SmartCardTokenWrapper.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SmartCardTokenWrapper.mm; sourceTree = ""; }; 39266A5920CFD93E002E3F23 /* AbstractSmartToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbstractSmartToken.swift; sourceTree = ""; }; - 39266A5B20CFDC41002E3F23 /* CdocParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CdocParser.h; sourceTree = ""; }; - 39266A5C20CFDC59002E3F23 /* CdocParser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CdocParser.m; sourceTree = ""; }; - 39266A5E20CFDCB9002E3F23 /* CdocInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CdocInfo.m; sourceTree = ""; }; - 39266A6020CFDCDF002E3F23 /* CdocInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CdocInfo.h; sourceTree = ""; }; - 39266A6120CFE36A002E3F23 /* CdocParserDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CdocParserDelegate.h; sourceTree = ""; }; - 39266A6220CFE3D4002E3F23 /* CdocParserDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CdocParserDelegate.m; sourceTree = ""; }; 393B66DF20DB94B4001DC89B /* cdoc.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = cdoc.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 3960E50320C02DA400D4D2FC /* CryptoDataFile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoDataFile.h; sourceTree = ""; }; - 3960E50420C02E5900D4D2FC /* CryptoDataFile.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CryptoDataFile.m; sourceTree = ""; }; 39852A4120AB2418004CB100 /* Decrypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Decrypt.h; sourceTree = ""; }; 39852A4220AB2418004CB100 /* Encrypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Encrypt.h; sourceTree = ""; }; - 39852A4620AB2418004CB100 /* DdocParserDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DdocParserDelegate.m; sourceTree = ""; }; 39852A4720AB2418004CB100 /* SmartCardTokenWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmartCardTokenWrapper.h; sourceTree = ""; }; 39852A4820AB2418004CB100 /* Decrypt.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Decrypt.mm; sourceTree = ""; }; 39852A4920AB2418004CB100 /* Encrypt.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Encrypt.mm; sourceTree = ""; }; - 39852A4A20AB2418004CB100 /* DdocParserDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DdocParserDelegate.h; sourceTree = ""; }; - 39E2B4CF20AD7A3400CA74A8 /* Addressee.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Addressee.m; sourceTree = ""; }; - 39E2B4D520AD7A3400CA74A8 /* Addressee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Addressee.h; sourceTree = ""; }; 4E01B4A62AEFDD3B00941723 /* build-cdoc.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "build-cdoc.sh"; sourceTree = ""; }; + 4E0454622D3BE73D0013DF23 /* CryptoDataFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoDataFile.swift; sourceTree = ""; }; + 4E17B8302D6485750063C5BF /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 4E17B8342D64A0FD0063C5BF /* X509CertificateType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = X509CertificateType.swift; sourceTree = ""; }; + 4E276E032D81A60600D78F40 /* Extensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Extensions.h; sourceTree = ""; }; 4E3681D72D40EAAD00D76DAB /* OpenLdap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenLdap.swift; sourceTree = ""; }; 4E3681DA2D40EAE800D76DAB /* MoppLdapConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoppLdapConfiguration.swift; sourceTree = ""; }; 4E8990852D710DBC0010CA1F /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; }; + 4EB03C7C2D3BE4FB00D5F9AC /* Addressee.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Addressee.swift; sourceTree = ""; }; + 4EB03C7E2D3BE6F700D5F9AC /* CdocInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CdocInfo.swift; sourceTree = ""; }; 4ED24ECB2D4F799800855FC3 /* build-openldap.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "build-openldap.sh"; sourceTree = ""; }; DFA40D2E2ADF635F003EF945 /* 3513523f.0 */ = {isa = PBXFileReference; lastKnownFileType = text; path = 3513523f.0; sourceTree = ""; }; DFC7CA442AE010C9009D85FF /* 9f4c149e.0 */ = {isa = PBXFileReference; lastKnownFileType = text; path = 9f4c149e.0; sourceTree = ""; }; @@ -92,6 +79,7 @@ buildActionMask = 2147483647; files = ( 4E8990862D710DC50010CA1F /* libxml2.tbd in Frameworks */, + 4E17B8322D6486040063C5BF /* libz.tbd in Frameworks */, 4EAC69122D481D1C00A53079 /* ASN1Decoder in Frameworks */, 393B66E020DB94B4001DC89B /* cdoc.framework in Frameworks */, ); @@ -124,54 +112,30 @@ children = ( DFC7CA442AE010C9009D85FF /* 9f4c149e.0 */, DFA40D2E2ADF635F003EF945 /* 3513523f.0 */, - 39E2B4CB20AD7A3400CA74A8 /* Ldap */, - 39E414E020AC5C9300141574 /* XmlParser */, + 39231FAD20AB1C6C00E1E2B4 /* CryptoLib.h */, + 4E276E032D81A60600D78F40 /* Extensions.h */, 39852A4120AB2418004CB100 /* Decrypt.h */, 39852A4820AB2418004CB100 /* Decrypt.mm */, 39852A4220AB2418004CB100 /* Encrypt.h */, 39852A4920AB2418004CB100 /* Encrypt.mm */, 39852A4720AB2418004CB100 /* SmartCardTokenWrapper.h */, 39266A5020CFBDF8002E3F23 /* SmartCardTokenWrapper.mm */, - 39266A5B20CFDC41002E3F23 /* CdocParser.h */, - 39266A5C20CFDC59002E3F23 /* CdocParser.m */, - 39231FAD20AB1C6C00E1E2B4 /* CryptoLib.h */, 39266A5920CFD93E002E3F23 /* AbstractSmartToken.swift */, - 39E2B4D520AD7A3400CA74A8 /* Addressee.h */, - 39E2B4CF20AD7A3400CA74A8 /* Addressee.m */, - 3960E50320C02DA400D4D2FC /* CryptoDataFile.h */, - 3960E50420C02E5900D4D2FC /* CryptoDataFile.m */, - 39266A5E20CFDCB9002E3F23 /* CdocInfo.m */, - 39266A6020CFDCDF002E3F23 /* CdocInfo.h */, - 4E17B8342D64A0FD0063C5BF /* X509CertificateType.swift */, - ); - path = CryptoLib; - sourceTree = ""; - }; - 39E2B4CB20AD7A3400CA74A8 /* Ldap */ = { - isa = PBXGroup; - children = ( + 4E0454622D3BE73D0013DF23 /* CryptoDataFile.swift */, + 4EB03C7C2D3BE4FB00D5F9AC /* Addressee.swift */, + 4EB03C7E2D3BE6F700D5F9AC /* CdocInfo.swift */, 4E3681D72D40EAAD00D76DAB /* OpenLdap.swift */, 4E3681DA2D40EAE800D76DAB /* MoppLdapConfiguration.swift */, + 4E17B8342D64A0FD0063C5BF /* X509CertificateType.swift */, ); - name = Ldap; - path = CryptoLib/Ldap; - sourceTree = SOURCE_ROOT; - }; - 39E414E020AC5C9300141574 /* XmlParser */ = { - isa = PBXGroup; - children = ( - 39852A4A20AB2418004CB100 /* DdocParserDelegate.h */, - 39852A4620AB2418004CB100 /* DdocParserDelegate.m */, - 39266A6120CFE36A002E3F23 /* CdocParserDelegate.h */, - 39266A6220CFE3D4002E3F23 /* CdocParserDelegate.m */, - ); - path = XmlParser; + path = CryptoLib; sourceTree = ""; }; D5B2B96758D5CBE2A4F80170 /* Frameworks */ = { isa = PBXGroup; children = ( 4E8990852D710DBC0010CA1F /* libxml2.tbd */, + 4E17B8302D6485750063C5BF /* libz.tbd */, 393B66DF20DB94B4001DC89B /* cdoc.framework */, ); name = Frameworks; @@ -184,15 +148,11 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 39231FAF20AB1C6C00E1E2B4 /* CryptoLib.h in Headers */, 39852A4B20AB2418004CB100 /* Decrypt.h in Headers */, 39852A4C20AB2418004CB100 /* Encrypt.h in Headers */, - 39852A5420AB2418004CB100 /* DdocParserDelegate.h in Headers */, 39852A5120AB2418004CB100 /* SmartCardTokenWrapper.h in Headers */, - 39E2B4DF20AD7A3400CA74A8 /* Addressee.h in Headers */, - 3960E50620C044EE00D4D2FC /* CryptoDataFile.h in Headers */, - 39266A6520CFE643002E3F23 /* CdocInfo.h in Headers */, - 39266A6420CFE63D002E3F23 /* CdocParser.h in Headers */, - 39231FAF20AB1C6C00E1E2B4 /* CryptoLib.h in Headers */, + 4E276E042D81A61000D78F40 /* Extensions.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -308,14 +268,11 @@ buildActionMask = 2147483647; files = ( 4EEE43222D7CF3C9003D0112 /* AbstractSmartToken.swift in Sources */, - 39266A5F20CFDCB9002E3F23 /* CdocInfo.m in Sources */, - 39266A6320CFE3D4002E3F23 /* CdocParserDelegate.m in Sources */, - 39266A5D20CFDC59002E3F23 /* CdocParser.m in Sources */, - 3960E50520C02E5900D4D2FC /* CryptoDataFile.m in Sources */, - 39852A5020AB2418004CB100 /* DdocParserDelegate.m in Sources */, + 4EB03C7D2D3BE4FB00D5F9AC /* Addressee.swift in Sources */, 4E17B8352D64A1080063C5BF /* X509CertificateType.swift in Sources */, + 4EB03C7F2D3BE6F700D5F9AC /* CdocInfo.swift in Sources */, 39852A5220AB2418004CB100 /* Decrypt.mm in Sources */, - 39E2B4D920AD7A3400CA74A8 /* Addressee.m in Sources */, + 4E0454632D3BE73D0013DF23 /* CryptoDataFile.swift in Sources */, 39852A5320AB2418004CB100 /* Encrypt.mm in Sources */, 39266A5120CFBDF8002E3F23 /* SmartCardTokenWrapper.mm in Sources */, 4E3681D92D40EAAD00D76DAB /* OpenLdap.swift in Sources */, @@ -375,7 +332,7 @@ COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_MODULE_VERIFIER = NO; + ENABLE_MODULE_VERIFIER = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -389,6 +346,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -432,7 +390,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; - ENABLE_MODULE_VERIFIER = NO; + ENABLE_MODULE_VERIFIER = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -444,6 +402,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; diff --git a/CryptoLib/CryptoLib/AbstractSmartToken.swift b/CryptoLib/CryptoLib/AbstractSmartToken.swift index 2fbc45ec9..df8f255e5 100644 --- a/CryptoLib/CryptoLib/AbstractSmartToken.swift +++ b/CryptoLib/CryptoLib/AbstractSmartToken.swift @@ -23,7 +23,7 @@ import Foundation @objc public protocol AbstractSmartToken { - func getCertificate() throws -> Data + func getCertificate() async throws -> Data func decrypt(_ data: Data) throws -> Data func derive(_ data: Data) throws -> Data func authenticate(_ data: Data) throws -> Data diff --git a/CryptoLib/CryptoLib/Addressee.h b/CryptoLib/CryptoLib/Addressee.h deleted file mode 100644 index ac6b0c805..000000000 --- a/CryptoLib/CryptoLib/Addressee.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// Addressee.h -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import - -@interface Addressee : NSObject -@property (nonatomic, strong) NSString *givenName; -@property (nonatomic, strong) NSString *surname; -@property (nonatomic, strong) NSString *identifier; -@property (nonatomic, strong) NSString *serialNumber; -@property (nonatomic, strong) NSData *cert; -@property (nonatomic, strong) NSDate *validTo; - -@end diff --git a/CryptoLib/CryptoLib/Addressee.m b/CryptoLib/CryptoLib/Addressee.m deleted file mode 100644 index 7d56299aa..000000000 --- a/CryptoLib/CryptoLib/Addressee.m +++ /dev/null @@ -1,28 +0,0 @@ -// -// Addressee.m -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import -#import "Addressee.h" - -@implementation Addressee - -@end diff --git a/CryptoLib/CryptoLib/Addressee.swift b/CryptoLib/CryptoLib/Addressee.swift new file mode 100644 index 000000000..7983f236e --- /dev/null +++ b/CryptoLib/CryptoLib/Addressee.swift @@ -0,0 +1,66 @@ +// +// Addressee.swift +// CryptoLib +/* + * Copyright 2017 - 2024 Riigi Infosüsteemi Amet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +import ASN1Decoder + +public class Addressee: NSObject { + @objc public var data: Data + public let identifier: String + public let givenName: String? + public let surname: String? + public let serialNumber: String? + public let certType: CertType + public var validTo: Date? + + init(cert: Data, x509: X509Certificate?) { + data = cert + let cn = x509?.subject(oid: .commonName)?.joined(separator: ",") ?? "" + let split = cn.split(separator: ",").map { String($0) } + if split.count > 1 { + surname = split[0] + givenName = split[1] + identifier = split[2] + } else { + surname = nil + givenName = nil + identifier = cn + } + serialNumber = x509?.subject(oid: .serialNumber)?.joined(separator: ",") + certType = x509?.certType() ?? .UnknownType + validTo = x509?.notAfter + } + + convenience init(cert: Data) { + self.init(cert: cert, x509: try? X509Certificate(der: cert)) + } + + public override func isEqual(_ object: Any?) -> Bool { + guard let other = object as? Addressee else { return false } + return + data == other.data && + identifier == other.identifier && + givenName == other.givenName && + surname == other.surname && + certType == other.certType && + validTo == other.validTo + } +} diff --git a/CryptoLib/CryptoLib/CdocInfo.h b/CryptoLib/CryptoLib/CdocInfo.h deleted file mode 100644 index ad5dc55f9..000000000 --- a/CryptoLib/CryptoLib/CdocInfo.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// CdocInfo.h -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import - -@class Addressee; -@class CryptoDataFile; - -@interface CdocInfo : NSObject -@property (nonatomic, strong) NSArray *addressees; -@property (nonatomic, strong) NSArray *dataFiles; -@end diff --git a/CryptoLib/CryptoLib/CdocInfo.m b/CryptoLib/CryptoLib/CdocInfo.m deleted file mode 100644 index 5febffa03..000000000 --- a/CryptoLib/CryptoLib/CdocInfo.m +++ /dev/null @@ -1,27 +0,0 @@ -// -// CdocInfo.m -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import -#import "CdocInfo.h" - -@implementation CdocInfo -@end diff --git a/CryptoLib/CryptoLib/CdocInfo.swift b/CryptoLib/CryptoLib/CdocInfo.swift new file mode 100644 index 000000000..8f8644903 --- /dev/null +++ b/CryptoLib/CryptoLib/CdocInfo.swift @@ -0,0 +1,91 @@ +// +// CdocInfo.swift +// CryptoLib +/* + * Copyright 2017 - 2024 Riigi Infosüsteemi Amet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +import Foundation + +public class CdocInfo: NSObject { + public let format: String + public let addressees: [Addressee] + public let dataFiles: [CryptoDataFile] + + @objc public init(cdoc1Path path: String) throws { + guard let parser = XMLParser(contentsOf: URL(fileURLWithPath: path)) else { + NSLog("Error: Unable to read file at \(path)") + throw NSError(domain: XMLParser.errorDomain, code: XMLParser.ErrorCode.internalError.rawValue, userInfo: [ + NSLocalizedDescriptionKey: "Failed to create XML parser for file at \(path)" + ]) + } + let delegate = CdocParserDelegate() + parser.externalEntityResolvingPolicy = .never + parser.delegate = delegate; + guard parser.parse() else { + NSLog("Error: Failed to parse XML") + throw parser.parserError! + } + format = delegate.format + addressees = delegate.addressees + dataFiles = delegate.dataFiles + } +} + +class CdocParserDelegate: NSObject, XMLParserDelegate { + public var format = String() + public var addressees: [Addressee] = [] + public var dataFiles: [CryptoDataFile] = [] + var data: String? = nil + var attr = String() + + func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String]) { + switch elementName { + case "ds:X509Certificate": + data = String() + case "denc:EncryptionProperty" where attributeDict["Name"] == "orig_file" || attributeDict["Name"] == "DocumentFormat": + attr = attributeDict["Name"] ?? "" + data = String() + default: break + } + } + + func parser(_ parser: XMLParser, foundCharacters string: String) { + if data != nil { + data! += string + } + } + + func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { + guard data != nil else { return } + switch (elementName, attr) { + case ("ds:X509Certificate", _): + if let data = Data(base64Encoded: data!, options: .ignoreUnknownCharacters) { + addressees.append(Addressee(cert: data)) + } + case ("denc:EncryptionProperty", "orig_file"): + if let filename = data!.split(separator: "|").first { + dataFiles.append(CryptoDataFile(filename: String(filename))) + } + case ("denc:EncryptionProperty", "DocumentFormat"): + format = data! + default: break + } + data = nil + } +} diff --git a/CryptoLib/CryptoLib/CdocParser.h b/CryptoLib/CryptoLib/CdocParser.h deleted file mode 100644 index b48fdc011..000000000 --- a/CryptoLib/CryptoLib/CdocParser.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// CdocParser.h -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import -#import "CdocInfo.h" - -@interface CdocParser : NSObject -- (CdocInfo*)parseCdocInfo:(NSString*)fullpath; -@end - - diff --git a/CryptoLib/CryptoLib/CdocParser.m b/CryptoLib/CryptoLib/CdocParser.m deleted file mode 100644 index fcb865861..000000000 --- a/CryptoLib/CryptoLib/CdocParser.m +++ /dev/null @@ -1,39 +0,0 @@ -// -// CdocParser.m -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#import "CdocParser.h" -#import "CdocInfo.h" -#import "CdocParserDelegate.h" - -@implementation CdocParser - -- (CdocInfo*)parseCdocInfo:(NSString*)fullpath { - NSData *data = [[NSData alloc] initWithContentsOfFile:fullpath]; - NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; - CdocParserDelegate *parserDelegate = [CdocParserDelegate new]; - [parser setDelegate:(id)parserDelegate]; - [parser parse]; - CdocInfo *response = [CdocInfo new]; - response.addressees = parserDelegate.addressees; - response.dataFiles = parserDelegate.dataFiles; - return response; -} -@end diff --git a/CryptoLib/CryptoLib/CryptoDataFile.h b/CryptoLib/CryptoLib/CryptoDataFile.h deleted file mode 100644 index ca4b1428f..000000000 --- a/CryptoLib/CryptoLib/CryptoDataFile.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// CryptoDataFile.h -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import - -@interface CryptoDataFile : NSObject -@property (nonatomic, strong) NSString *filename; -@property (nonatomic, strong) NSString *filePath; - -@end diff --git a/CryptoLib/CryptoLib/CryptoDataFile.m b/CryptoLib/CryptoLib/CryptoDataFile.m deleted file mode 100644 index f4edfd1d4..000000000 --- a/CryptoLib/CryptoLib/CryptoDataFile.m +++ /dev/null @@ -1,28 +0,0 @@ -// -// DataFile.m -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import -#import "CryptoDataFile.h" - -@implementation CryptoDataFile - -@end diff --git a/CryptoLib/CryptoLib/XmlParser/DdocParserDelegate.h b/CryptoLib/CryptoLib/CryptoDataFile.swift similarity index 73% rename from CryptoLib/CryptoLib/XmlParser/DdocParserDelegate.h rename to CryptoLib/CryptoLib/CryptoDataFile.swift index b68d4ca8b..3646ba6fd 100644 --- a/CryptoLib/CryptoLib/XmlParser/DdocParserDelegate.h +++ b/CryptoLib/CryptoLib/CryptoDataFile.swift @@ -1,5 +1,5 @@ // -// DdocParserDelegate.h +// CryptoDataFile.swift // CryptoLib /* * Copyright 2017 - 2024 Riigi Infosüsteemi Amet @@ -20,12 +20,14 @@ * */ -#import +import Foundation -@interface DdocParserDelegate : NSObject -{ +public class CryptoDataFile: NSObject { + @objc public let filename: String + @objc public let filePath: String? + + public init(filename: String, filePath: String? = nil) { + self.filename = filename + self.filePath = filePath + } } -@property (nonatomic, retain) NSMutableDictionary *dictionary; -@property (nonatomic, retain) NSString *lastKey; -@property (nonatomic, retain) NSString *currentElement; -@end diff --git a/CryptoLib/CryptoLib/CryptoLib.h b/CryptoLib/CryptoLib/CryptoLib.h index ea0306392..514a81497 100644 --- a/CryptoLib/CryptoLib/CryptoLib.h +++ b/CryptoLib/CryptoLib/CryptoLib.h @@ -30,9 +30,5 @@ FOUNDATION_EXPORT const unsigned char CryptoLibVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import -#import -#import -#import -#import #import #import diff --git a/CryptoLib/CryptoLib/Decrypt.h b/CryptoLib/CryptoLib/Decrypt.h index 5200322c3..1a4659e51 100644 --- a/CryptoLib/CryptoLib/Decrypt.h +++ b/CryptoLib/CryptoLib/Decrypt.h @@ -23,7 +23,14 @@ #import @protocol AbstractSmartToken; +@class CdocInfo; + +NS_ASSUME_NONNULL_BEGIN @interface Decrypt : NSObject -+ (NSDictionary * _Nullable)decryptFile:(NSString * _Nonnull)fullPath withToken:(id _Nonnull)smartToken error:(NSError * _Nullable * _Nullable)error; ++ (CdocInfo * _Nullable)cdocInfo:(NSString *)fullPath error:(NSError **)error; ++ (void)decryptFile:(NSString *)fullPath withToken:(id)smartToken + completion:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))completion; @end + +NS_ASSUME_NONNULL_END diff --git a/CryptoLib/CryptoLib/Decrypt.mm b/CryptoLib/CryptoLib/Decrypt.mm index 69c916158..07f913061 100644 --- a/CryptoLib/CryptoLib/Decrypt.mm +++ b/CryptoLib/CryptoLib/Decrypt.mm @@ -21,48 +21,72 @@ */ #import "Decrypt.h" +#import "Extensions.h" #import "SmartCardTokenWrapper.h" -#import "DdocParserDelegate.h" +#import -#import -#import +#include +#include +#include @implementation Decrypt -+ (NSDictionary *)decryptFile:(NSString *)fullPath withToken:(id)smartToken error:(NSError**)error { ++ (CdocInfo*)cdocInfo:(NSString *)fullPath error:(NSError**)error { + return [[CdocInfo alloc] initWithCdoc1Path:fullPath error:error]; +} + ++ (void)decryptFile:(NSString *)fullPath withToken:(id)smartToken + completion:(void (^)(NSDictionary *, NSError *))completion { + [smartToken getCertificateWithCompletionHandler:^(NSData *certData, NSError *error) { + auto cert = [certData toVector]; + if(cert.empty()) { + return completion(nil, error); + } + + SmartCardTokenWrapper token(smartToken); + std::unique_ptr reader(libcdoc::CDocReader::createReader(fullPath.UTF8String, nullptr, &token, nullptr)); + + auto idx = reader->getLockForCert(cert); + if(idx < 0) { + return completion(nil, [NSError cryptoError:@"Failed to find lock for cert"]); + } + std::vector fmk; + if(reader->getFMK(fmk, unsigned(idx)) != 0 || fmk.empty()) { + return completion(nil, token.lastError() ?: [NSError cryptoError:@"Failed to get FMK"]); + } + if(reader->beginDecryption(fmk) != 0) { + return completion(nil, [NSError cryptoError:@"Failed to start encryption"]); + } - std::string encodedFullPath = std::string([fullPath UTF8String]); - CDOCReader cdocReader(encodedFullPath); - SmartCardTokenWrapper token(smartToken); + NSMutableDictionary *response = [NSMutableDictionary new]; + std::string name; + int64_t size{}; + while((reader->nextFile(name, size)) == 0) + { + NSMutableData *data = [[NSMutableData alloc] initWithLength:16 * 1024]; + NSUInteger currentLength = 0; - std::vector decryptedData = cdocReader.decryptData(&token); - *error = token.lastError(); - if (*error != nil){ - return nil; - } - NSData *decrypted = [NSData dataWithBytes:decryptedData.data() length:decryptedData.size()]; - std::string filename = cdocReader.fileName(); - std::string mimetype = cdocReader.mimeType(); + uint64_t bytesRead = 0; + while (true) { + bytesRead = reader->readData(reinterpret_cast(data.mutableBytes) + currentLength, 16 * 1024); + if (bytesRead < 0) { + NSLog(@"Error reading data from file: %s", name.c_str()); + return completion(nil, [NSError cryptoError:@"Failed to decrypt file"]); + } - NSMutableDictionary *response = [NSMutableDictionary new]; - NSString *nsFilename = [NSString stringWithCString:filename.c_str() encoding: NSUTF8StringEncoding]; - if ([[nsFilename pathExtension] isEqualToString: @"ddoc"]){ - NSXMLParser *parser = [[NSXMLParser alloc] initWithData:decrypted]; - DdocParserDelegate *parserDelegate = [[DdocParserDelegate alloc] init]; - [parser setDelegate:(id)parserDelegate]; - [parser parse]; - NSMutableDictionary *fileDictionary; - fileDictionary = parserDelegate.dictionary; - for (id key in fileDictionary){ - NSString *value = [fileDictionary objectForKey:key]; - NSData *nsdataFromBase64String = [[NSData alloc] initWithBase64EncodedString: value options:NSDataBase64DecodingIgnoreUnknownCharacters]; - [response setObject:nsdataFromBase64String forKey:key]; - + currentLength += bytesRead; + [data setLength:currentLength]; + if (bytesRead == 0) { + break; + } + [data increaseLengthBy:16 * 1024]; + } + [response setObject:data forKey:[NSString stringWithStdString:name]]; } - } else { - [response setObject:decrypted forKey:nsFilename]; - } - return response; + if (reader->finishDecryption() != 0) + return completion(nil, [NSError cryptoError:@"Failed to end encryption"]); + return completion(response, nil); + }]; } @end diff --git a/CryptoLib/CryptoLib/Encrypt.h b/CryptoLib/CryptoLib/Encrypt.h index 3e04c9f00..218de508f 100644 --- a/CryptoLib/CryptoLib/Encrypt.h +++ b/CryptoLib/CryptoLib/Encrypt.h @@ -25,6 +25,13 @@ @class Addressee; @class CryptoDataFile; -@interface Encrypt : NSObject -+ (BOOL)encryptFile: (NSString * _Nonnull)fullPath withDataFiles :(NSArray * _Nonnull) dataFiles withAddressees: (NSArray * _Nonnull) addressees; +NS_ASSUME_NONNULL_BEGIN + +@interface Encrypt: NSObject + ++ (void)encryptFile:(NSString *)fullPath withDataFiles:(NSArray *)dataFiles + withAddressees:(NSArray *)addressees completion:(void (^)(NSError * _Nullable))completion; + @end + +NS_ASSUME_NONNULL_END diff --git a/CryptoLib/CryptoLib/Encrypt.mm b/CryptoLib/CryptoLib/Encrypt.mm index 3465b38ca..a5e5e7ef2 100644 --- a/CryptoLib/CryptoLib/Encrypt.mm +++ b/CryptoLib/CryptoLib/Encrypt.mm @@ -20,33 +20,57 @@ * */ - #import "Encrypt.h" -#import "Addressee.h" -#import "CryptoDataFile.h" +#import "Extensions.h" -#import +#import -@implementation Encrypt +#include +#include -+ (BOOL)encryptFile: (NSString *)fullPath withDataFiles :(NSArray *) dataFiles withAddressees: (NSArray *) addressees { +@implementation Encrypt - std::string encodedFullPath = std::string([fullPath UTF8String]); ++ (void)encryptFile:(NSString *)fullPath withDataFiles:(NSArray *)dataFiles withAddressees:(NSArray *)addressees + completion:(void (^)(NSError*))completion { + std::unique_ptr writer(libcdoc::CDocWriter::createWriter(1, fullPath.UTF8String, nullptr, nullptr, nullptr)); - CDOCWriter cdocWriter(encodedFullPath, "http://www.w3.org/2009/xmlenc11#aes256-gcm"); + if (!writer) { + return completion([NSError cryptoError:@"Failed to create writer"]); + } - for (CryptoDataFile *dataFile in dataFiles) { - std::string encodedDataFilePath = std::string([dataFile.filePath UTF8String]); - std::string encodedFilename = std::string([dataFile.filename UTF8String]); - cdocWriter.addFile(encodedFilename, "application/octet-stream", encodedDataFilePath); + if (writer->beginEncryption() != 0) { + return completion([NSError cryptoError:@"Failed to start encryption"]); } + for (Addressee *addressee in addressees) { - NSData *cert = addressee.cert; - unsigned char *buffer = reinterpret_cast(const_cast(cert.bytes)); - cdocWriter.addRecipient(std::vector(buffer, buffer + cert.length)); + if (writer->addRecipient(libcdoc::Recipient::makeCertificate({}, [addressee.data toVector])) != 0) { + return completion([NSError cryptoError:@"Failed to add recipien"]); + } } - return cdocWriter.encrypt(); + for (CryptoDataFile *dataFile in dataFiles) { + NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:dataFile.filePath]; + if (!fileHandle) { + return completion([NSError cryptoError:[NSString stringWithFormat:@"Failed to open file at path: %@", dataFile.filePath]]); + } + + if (writer->addFile(dataFile.filename.UTF8String, [fileHandle seekToEndOfFile]) != 0) { + [fileHandle closeFile]; + return completion([NSError cryptoError:[NSString stringWithFormat:@"Failed to add file to container: %@", dataFile.filename]]); + } + [fileHandle seekToFileOffset:0]; + + NSUInteger blockSize = 1024 * 16; + NSData *data; + while ((data = [fileHandle readDataOfLength:blockSize]) && data.length > 0) { + if (writer->writeData(reinterpret_cast(data.bytes), data.length) != 0) { + [fileHandle closeFile]; + return completion([NSError cryptoError:[NSString stringWithFormat:@"Failed to write file to container: %@", dataFile.filename]]); + } + } + [fileHandle closeFile]; + } + completion(writer->finishEncryption() == 0 ? nil : [NSError cryptoError:@"Failed to finish encryption"]); } @end diff --git a/CryptoLib/CryptoLib/Extensions.h b/CryptoLib/CryptoLib/Extensions.h new file mode 100644 index 000000000..1318056a9 --- /dev/null +++ b/CryptoLib/CryptoLib/Extensions.h @@ -0,0 +1,75 @@ +// +// Decrypt.h +// CryptoLib +/* + * Copyright 2017 - 2024 Riigi Infosüsteemi Amet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#import + +#include +#include + +@interface NSError (CryptoLib) ++ (NSError*)cryptoError:(NSString*)msg; +@end + +@interface NSString (std_string) +- (std::string)toString; +@end + +@interface NSData (std_vector) +- (std::vector)toVector; +@end + +@implementation NSString (std_string) ++ (instancetype)stringWithStdString:(const std::string&)data { + return data.empty() ? nil : [NSString stringWithUTF8String:data.c_str()]; +} + +- (std::string)toString { + if (self == nil) { + return {}; + } + return {self.UTF8String}; +} +@end + +@implementation NSData (std_vector) ++ (instancetype)dataFromVector:(const std::vector&)data { + return data.empty() ? nil : [NSData dataWithBytes:(void *)data.data() length:data.size()]; +} + ++ (instancetype)dataFromVectorNoCopy:(const std::vector&)data { + return data.empty() ? nil : [NSData dataWithBytesNoCopy:(void *)data.data() length:data.size() freeWhenDone:0]; +} + +- (std::vector)toVector { + if (self == nil) { + return {}; + } + const auto *p = reinterpret_cast(self.bytes); + return {p, std::next(p, self.length)}; +} +@end + +@implementation NSError (CryptoLib) ++ (NSError*)cryptoError:(NSString *)msg { + return [[NSError alloc] initWithDomain:@"ee.ria.digidoc.CryptoLib" code:1000 userInfo: @{NSLocalizedDescriptionKey: msg}]; +} +@end diff --git a/CryptoLib/CryptoLib/Ldap/MoppLdapConfiguration.swift b/CryptoLib/CryptoLib/MoppLdapConfiguration.swift similarity index 100% rename from CryptoLib/CryptoLib/Ldap/MoppLdapConfiguration.swift rename to CryptoLib/CryptoLib/MoppLdapConfiguration.swift diff --git a/CryptoLib/CryptoLib/Ldap/OpenLdap.swift b/CryptoLib/CryptoLib/OpenLdap.swift similarity index 92% rename from CryptoLib/CryptoLib/Ldap/OpenLdap.swift rename to CryptoLib/CryptoLib/OpenLdap.swift index 538b698c2..b41af3e29 100644 --- a/CryptoLib/CryptoLib/Ldap/OpenLdap.swift +++ b/CryptoLib/CryptoLib/OpenLdap.swift @@ -252,21 +252,7 @@ public class OpenLdap { !x509.extendedKeyUsage.contains(OID.serverAuth.rawValue), type != .ESealType || !x509.extendedKeyUsage.contains(OID.clientAuth.rawValue), type != .MobileIDType && type != .UnknownType { - let cn = x509.subject(oid: OID.commonName)?.joined(separator: ",") ?? "" - let serialNumber = x509.subject(oid: OID.serialNumber)?.joined(separator: ",") ?? "" - let split = cn.split(separator: ",").map { String($0) } - let addressee = Addressee() - if split.count == 3 { - addressee.surname = split[0] - addressee.givenName = split[1] - addressee.identifier = split[2] - } else { - addressee.identifier = cn - } - addressee.serialNumber = serialNumber - addressee.cert = data - addressee.validTo = x509.notAfter ?? Date() - result.append(addressee) + result.append(Addressee(cert: data, x509: x509)) } } return result diff --git a/CryptoLib/CryptoLib/SmartCardTokenWrapper.h b/CryptoLib/CryptoLib/SmartCardTokenWrapper.h index a5e1ddbd6..e5bd96d5e 100644 --- a/CryptoLib/CryptoLib/SmartCardTokenWrapper.h +++ b/CryptoLib/CryptoLib/SmartCardTokenWrapper.h @@ -22,23 +22,21 @@ #if __cplusplus -#import "cdoc/Token.h" - +#import #import - #include @protocol AbstractSmartToken; -class SmartCardTokenWrapper: public Token +class SmartCardTokenWrapper: public libcdoc::CryptoBackend { public: SmartCardTokenWrapper(id smartToken); ~SmartCardTokenWrapper() noexcept; - std::vector cert() const final; - std::vector decrypt(const std::vector &data) const final; - std::vector derive(const std::vector &publicKey) const final; + libcdoc::result_t deriveECDH1(std::vector &dst, const std::vector &public_key, unsigned int idx) final; + libcdoc::result_t decryptRSA(std::vector &dst, const std::vector &data, bool oaep, unsigned int idx) final; + libcdoc::result_t sign(std::vector &dst, HashAlgorithm algorithm, const std::vector &digest, unsigned int idx) final; NSError* lastError() const; private: diff --git a/CryptoLib/CryptoLib/SmartCardTokenWrapper.mm b/CryptoLib/CryptoLib/SmartCardTokenWrapper.mm index 024f6cf84..812c84370 100644 --- a/CryptoLib/CryptoLib/SmartCardTokenWrapper.mm +++ b/CryptoLib/CryptoLib/SmartCardTokenWrapper.mm @@ -22,23 +22,10 @@ */ #import "SmartCardTokenWrapper.h" +#import "Extensions.h" #import -@implementation NSData (std_vector) -+ (instancetype)dataFromVectorNoCopy:(const std::vector&)data { - return data.empty() ? nil : [NSData dataWithBytesNoCopy:(void *)data.data() length:data.size() freeWhenDone:NO]; -} - -- (std::vector)toVector { - if (self == nil) { - return {}; - } - const auto *p = reinterpret_cast(self.bytes); - return {p, std::next(p, self.length)}; -} -@end - struct SmartCardTokenWrapper::Private { id smartTokenClass; NSError *error; @@ -58,26 +45,26 @@ + (instancetype)dataFromVectorNoCopy:(const std::vector&)data { return token->error; } -std::vector SmartCardTokenWrapper::cert() const +libcdoc::result_t SmartCardTokenWrapper::deriveECDH1(std::vector& dst, const std::vector &public_key, unsigned int idx) { NSError *error = nil; - auto result = [[token->smartTokenClass getCertificateAndReturnError:&error] toVector]; + dst = [[token->smartTokenClass derive:[NSData dataFromVectorNoCopy:public_key] error:&error] toVector]; token->error = error; - return result; + return dst.empty() ? libcdoc::CRYPTO_ERROR : libcdoc::OK; } -std::vector SmartCardTokenWrapper::decrypt(const std::vector &data) const +libcdoc::result_t SmartCardTokenWrapper::decryptRSA(std::vector& dst, const std::vector& data, bool oaep, unsigned int idx) { NSError *error = nil; - auto result = [[token->smartTokenClass derive:[NSData dataFromVectorNoCopy:data] error:&error] toVector]; + dst = [[token->smartTokenClass decrypt:[NSData dataFromVectorNoCopy:data] error:&error] toVector]; token->error = error; - return result; + return dst.empty() ? libcdoc::CRYPTO_ERROR : libcdoc::OK; } -std::vector SmartCardTokenWrapper::derive(const std::vector &publicKey) const +libcdoc::result_t SmartCardTokenWrapper::sign(std::vector &dst, HashAlgorithm algorithm, const std::vector &digest, unsigned int idx) { NSError *error = nil; - auto result = [[token->smartTokenClass derive:[NSData dataFromVectorNoCopy:publicKey] error:&error] toVector]; + dst = [[token->smartTokenClass authenticate:[NSData dataFromVectorNoCopy:digest] error:&error] toVector]; token->error = error; - return result; + return dst.empty() ? libcdoc::CRYPTO_ERROR : libcdoc::OK; } diff --git a/CryptoLib/CryptoLib/X509CertificateType.swift b/CryptoLib/CryptoLib/X509CertificateType.swift index bd5595d89..80cb9598b 100644 --- a/CryptoLib/CryptoLib/X509CertificateType.swift +++ b/CryptoLib/CryptoLib/X509CertificateType.swift @@ -22,17 +22,17 @@ import ASN1Decoder -extension X509Certificate { - public enum CertType { - case UnknownType - case IDCardType - case DigiIDType - case EResidentType - case MobileIDType - case SmartIDType - case ESealType - } +@objc public enum CertType: UInt { + case UnknownType + case IDCardType + case DigiIDType + case EResidentType + case MobileIDType + case SmartIDType + case ESealType +} +extension X509Certificate { public func certType() -> CertType { if let ext = extensionObject(oid: OID.certificatePolicies) as? X509Certificate.CertificatePoliciesExtension { for policy in ext.policies ?? [] { diff --git a/CryptoLib/CryptoLib/XmlParser/CdocParserDelegate.h b/CryptoLib/CryptoLib/XmlParser/CdocParserDelegate.h deleted file mode 100644 index 5d04f947d..000000000 --- a/CryptoLib/CryptoLib/XmlParser/CdocParserDelegate.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// CdocParserDelegate.h -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import -#import "Addressee.h" -#import "CryptoDataFile.h" -@interface CdocParserDelegate : NSObject -{ -} -@property (nonatomic, strong) NSMutableArray *addressees; -@property (nonatomic, strong) NSMutableArray *dataFiles; -@property (nonatomic, retain) NSString *currentFilenameNode; -@property (nonatomic) BOOL isNextCharactersFilename; -@property (nonatomic) BOOL isNextCharactersCertificate; -@property (nonatomic, strong) Addressee *lastAddressee; -@end diff --git a/CryptoLib/CryptoLib/XmlParser/CdocParserDelegate.m b/CryptoLib/CryptoLib/XmlParser/CdocParserDelegate.m deleted file mode 100644 index 4331f9c38..000000000 --- a/CryptoLib/CryptoLib/XmlParser/CdocParserDelegate.m +++ /dev/null @@ -1,89 +0,0 @@ -// -// CdocParserDelegate.m -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import "CdocParserDelegate.h" -@interface CdocParserDelegate () -@end - -@implementation CdocParserDelegate { -} - -- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { - if ([elementName isEqualToString:@"denc:EncryptedKey"]) { - if (_addressees == nil){ - _addressees = [NSMutableArray new]; - } - if (_lastAddressee == nil){ - _lastAddressee = [Addressee new]; - } - NSString *attribute = attributeDict[@"Recipient"]; - NSArray *cn = [attribute componentsSeparatedByString:@","]; - Addressee *addressee = [Addressee new]; - if (cn.count > 1) { - addressee.surname = cn[0]; - addressee.givenName = cn[1]; - addressee.identifier = cn[2]; - } else { - addressee.identifier = cn[0]; - } - [_addressees addObject:addressee]; - _lastAddressee = addressee; - } - if ([elementName isEqualToString:@"ds:X509Certificate"]) { - _isNextCharactersCertificate = YES; - } - if ([elementName isEqualToString:@"denc:EncryptionProperty"] && [[attributeDict valueForKey: @"Name"] isEqual: @"orig_file"]) { - _isNextCharactersFilename = YES; - } -} - --(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { - if (_isNextCharactersFilename) { - if (_currentFilenameNode) { - _currentFilenameNode = [_currentFilenameNode stringByAppendingString:string]; - } else { - _currentFilenameNode = string; - } - } - - if (_isNextCharactersCertificate) { - _lastAddressee.cert = [[NSData alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters]; - } -} - -- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName { - if (_isNextCharactersFilename) { - if (_dataFiles == nil){ - _dataFiles = [NSMutableArray new]; - } - NSArray *filenameWithBytesLength = [_currentFilenameNode componentsSeparatedByString:@"|"]; - NSString *filename = filenameWithBytesLength[0]; - CryptoDataFile *dataFile = [CryptoDataFile new]; - dataFile.filename = filename; - [_dataFiles addObject:dataFile]; - } - _currentFilenameNode = nil; - _isNextCharactersFilename = NO; - _isNextCharactersCertificate = NO; -} - -@end diff --git a/CryptoLib/CryptoLib/XmlParser/DdocParserDelegate.m b/CryptoLib/CryptoLib/XmlParser/DdocParserDelegate.m deleted file mode 100644 index fb314e146..000000000 --- a/CryptoLib/CryptoLib/XmlParser/DdocParserDelegate.m +++ /dev/null @@ -1,79 +0,0 @@ -// -// DdocParserDelegate.m -// CryptoLib -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#if DEBUG -#define printLog(...) NSLog(__VA_ARGS__) -#else -#define printLog(...) -#endif - -#import "DdocParserDelegate.h" -@interface DdocParserDelegate () -@end - -@implementation DdocParserDelegate { - -} - -- (void) parserDidStartDocument:(NSXMLParser *)parser { - printLog(@"parserDidStartDocument"); -} - -- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { - printLog(@"didStartElement --> %@", elementName); - - if ([elementName isEqualToString:@"DataFile"]) { - if (_dictionary == nil){ - _dictionary = [NSMutableDictionary new]; - } - NSString *attribute = attributeDict[@"Filename"]; - [_dictionary setObject:@"" forKey:attribute]; - _lastKey = attribute; - printLog(@"didStartElement --> %@", attributeDict[@"Filename"]); - } -} - --(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { - - // If parsing ddoc original filenames, sometimes filename may contain new line symbols - if (string != nil && [string length] != 0 && ![string isEqualToString:@"\n "] && ![string isEqualToString:@"\n"]){ - string = [string stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]]; - if (_currentElement == nil ) { - _currentElement = [NSString new]; - } - _currentElement = [NSString stringWithFormat:@"%@%@", _currentElement, string]; - } - printLog(@"foundCharacters --> %@", string); -} - -- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { - if ([_currentElement length] != 0) { - [_dictionary setValue:_currentElement forKey:_lastKey]; - _currentElement = @""; - } - printLog(@"didEndElement --> %@", elementName); -} - -- (void) parserDidEndDocument:(NSXMLParser *)parser { - printLog(@"parserDidEndDocument"); -} -@end diff --git a/CryptoLib/build-cdoc.sh b/CryptoLib/build-cdoc.sh index 004965c83..6624ca509 100755 --- a/CryptoLib/build-cdoc.sh +++ b/CryptoLib/build-cdoc.sh @@ -3,19 +3,22 @@ export PATH=$PATH:/usr/local/bin:/opt/homebrew/bin SOURCE_DIR=${DERIVED_SOURCES_DIR}/cdoc if [ ! -d ${SOURCE_DIR} ]; then - git clone -b mopp https://github.com/metsma/cdoc.git ${SOURCE_DIR}; + git clone https://github.com/open-eid/libcdoc.git ${SOURCE_DIR}; fi cmake \ - -DINSTALL_FRAMEWORKDIR=${BUILT_PRODUCTS_DIR} \ + -DFRAMEWORK_DESTINATION=${BUILT_PRODUCTS_DIR} \ -DCMAKE_INSTALL_PREFIX=${BUILT_PRODUCTS_DIR} \ -DCMAKE_BUILD_TYPE=${CONFIGURATION} \ -DCMAKE_OSX_SYSROOT=${PLATFORM_NAME} \ -DCMAKE_OSX_ARCHITECTURES="${ARCHS// /;}" \ -DCMAKE_OSX_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET} \ + -DCMAKE_CXX_FLAGS="-D_LIBCPP_DISABLE_AVAILABILITY" \ -DBUILD_SHARED_LIBS=NO \ + -DBUILD_TOOLS=NO \ -DOPENSSL_ROOT_DIR=${PROJECT_DIR}/../MoppLib/MoppLib/libdigidocpp/libdigidocpp.${PLATFORM_NAME} \ -DCMAKE_DISABLE_FIND_PACKAGE_SWIG=YES \ -DCMAKE_DISABLE_FIND_PACKAGE_Doxygen=YES \ + -DCMAKE_DISABLE_FIND_PACKAGE_Boost=YES \ -S ${SOURCE_DIR} -B ${TARGET_TEMP_DIR} cmake --build ${TARGET_TEMP_DIR} cmake --install ${TARGET_TEMP_DIR} diff --git a/MoppApp/MoppApp.xcodeproj/project.pbxproj b/MoppApp/MoppApp.xcodeproj/project.pbxproj index 05ddef35b..5f33cb99c 100644 --- a/MoppApp/MoppApp.xcodeproj/project.pbxproj +++ b/MoppApp/MoppApp.xcodeproj/project.pbxproj @@ -19,7 +19,6 @@ 3921CAAD20B819B500BF3178 /* ContainerNoAddresseesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3921CAAC20B819B500BF3178 /* ContainerNoAddresseesCell.swift */; }; 3921CAAF20B826E700BF3178 /* AddresseeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3921CAAE20B826E700BF3178 /* AddresseeViewController.swift */; }; 393B66BA20D7EC9D001DC89B /* WrapperUIBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393B66B920D7EC9D001DC89B /* WrapperUIBarButtonItem.swift */; }; - 39487CBE210B18F90082D910 /* CdocParserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39487CBD210B18F90082D910 /* CdocParserDelegate.swift */; }; 399C01EA20BD98730056D7AC /* ContainerFoundAddresseeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 399C01E920BD98730056D7AC /* ContainerFoundAddresseeCell.swift */; }; 39CDA7EA20ADBCEC006E2E9F /* Crypto.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 39CDA7E920ADBCEB006E2E9F /* Crypto.storyboard */; }; 39CDA7EE20ADBE93006E2E9F /* CryptoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CDA7ED20ADBE93006E2E9F /* CryptoViewController.swift */; }; @@ -341,7 +340,6 @@ 3921CAAC20B819B500BF3178 /* ContainerNoAddresseesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerNoAddresseesCell.swift; sourceTree = ""; }; 3921CAAE20B826E700BF3178 /* AddresseeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddresseeViewController.swift; sourceTree = ""; }; 393B66B920D7EC9D001DC89B /* WrapperUIBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrapperUIBarButtonItem.swift; sourceTree = ""; }; - 39487CBD210B18F90082D910 /* CdocParserDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CdocParserDelegate.swift; sourceTree = ""; }; 399C01E920BD98730056D7AC /* ContainerFoundAddresseeCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerFoundAddresseeCell.swift; sourceTree = ""; }; 39CDA7E920ADBCEB006E2E9F /* Crypto.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Crypto.storyboard; sourceTree = ""; }; 39CDA7ED20ADBE93006E2E9F /* CryptoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoViewController.swift; sourceTree = ""; }; @@ -916,7 +914,6 @@ DFC18364261B387C0094E455 /* SaveableContainerActions.swift */, C5E7D08C2031B1040081416F /* NativeShare.swift */, C5A1D1CC2031D5B80024CD4C /* ContainerActions.swift */, - 39487CBD210B18F90082D910 /* CdocParserDelegate.swift */, DF7F611826399B5400747B7D /* ContainerRemovalActions.swift */, ); name = Shared; @@ -1612,7 +1609,6 @@ DFC2ADC229437790008A1CD2 /* AccessibilityViewController.swift in Sources */, 393B66BA20D7EC9D001DC89B /* WrapperUIBarButtonItem.swift in Sources */, DFC2ADC6294377AC008A1CD2 /* AccessibilityViewTextType.swift in Sources */, - 39487CBE210B18F90082D910 /* CdocParserDelegate.swift in Sources */, DFD176D423F427AD00E2CC52 /* TSLVersionChecker.swift in Sources */, DF4B8418284008CF005CB875 /* SignatureDetail.swift in Sources */, DFBDF1F427D8DD4100A5CF3C /* RoleAndAddressViewController.swift in Sources */, diff --git a/MoppApp/MoppApp/AddresseeActions.swift b/MoppApp/MoppApp/AddresseeActions.swift index c440e57ca..d56839103 100644 --- a/MoppApp/MoppApp/AddresseeActions.swift +++ b/MoppApp/MoppApp/AddresseeActions.swift @@ -20,33 +20,29 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ -import Foundation + import ASN1Decoder -import CryptoLib protocol AddresseeActions { - func displayAddresseeType(_ type: X509Certificate.CertType?) -> String - func determineName(addressee: Addressee) -> String } extension AddresseeActions { func determineName(addressee: Addressee) -> String { if addressee.givenName == nil { - return "\(addressee.identifier ?? ""), \(addressee.serialNumber ?? "")" + return "\(addressee.identifier), \(addressee.serialNumber ?? "")" } else { - return "\(addressee.surname.uppercased()), \(addressee.givenName.uppercased()), \(addressee.identifier.uppercased())" + return "\(addressee.surname?.uppercased() ?? ""), \(addressee.givenName?.uppercased() ?? ""), \(addressee.identifier.uppercased())" } } func determineInfo(addressee: Addressee) -> String { - let x509 = try? X509Certificate(der: addressee.cert) - let addresseeType = displayAddresseeType(x509?.certType()) - let validTo = "\(L(LocKey.cryptoValidTo)) \(MoppDateFormatter.shared.ddMMYYYY(toString: x509?.notAfter ?? Date()))" + let addresseeType = displayAddresseeType(addressee.certType) + let validTo = addressee.validTo != nil ? "\(L(LocKey.cryptoValidTo)) \(MoppDateFormatter.shared.ddMMYYYY(toString: addressee.validTo!))" : "" return "\(addresseeType) (\(validTo))" } - func displayAddresseeType(_ type: X509Certificate.CertType?) -> String { + func displayAddresseeType(_ type: CertType?) -> String { switch type { case .IDCardType: return L(.cryptoTypeIdCard) diff --git a/MoppApp/MoppApp/AddresseeViewController.swift b/MoppApp/MoppApp/AddresseeViewController.swift index 690583302..ac71997ed 100644 --- a/MoppApp/MoppApp/AddresseeViewController.swift +++ b/MoppApp/MoppApp/AddresseeViewController.swift @@ -260,13 +260,7 @@ extension AddresseeViewController : UITableViewDataSource { cell.accessibilityLabel = "" cell.accessibilityUserInputLabels = [""] } - let isSelected = selectedAddressees.contains { element in - if ((element as Addressee).cert == (foundAddressees[row] as Addressee).cert) { - return true - } - return false - } - let isAddButtonDisabled = selectedIndexes.contains(row) || isSelected + let isAddButtonDisabled = selectedIndexes.contains(row) || selectedAddressees.contains(foundAddressees[row]) cell.populate(addressee: foundAddressees[row] as Addressee, index: row, isAddButtonDisabled: isAddButtonDisabled) if indexPath.row == 0 { UIAccessibility.post(notification: .layoutChanged, argument: cell) @@ -413,14 +407,9 @@ extension AddresseeViewController : ContainerFoundAddresseeCellDelegate { } func addAddresseeToSelectedArea(addressee: Addressee) { - if !selectedAddressees.contains(where: {( - ($0.givenName != nil && $0.givenName == addressee.givenName && - $0.surname != nil && $0.surname == addressee.surname) || - $0.identifier == addressee.identifier) && $0.cert == addressee.cert && $0.validTo == addressee.validTo - }) { + if !selectedAddressees.contains(addressee) { selectedAddressees.insert(addressee, at: 0) } - self.tableView.reloadData() } diff --git a/MoppApp/MoppApp/CdocParserDelegate.swift b/MoppApp/MoppApp/CdocParserDelegate.swift deleted file mode 100644 index bf1f5ccfd..000000000 --- a/MoppApp/MoppApp/CdocParserDelegate.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// CdocParserDelegate.swift -// MoppApp -// -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -import Foundation - -extension MoppApp: XMLParserDelegate { - - func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) { - if elementName == "denc:EncryptionProperty" { - if let name = attributeDict["Name"] { - if(name == "DocumentFormat"){ - currentElement = elementName - } - } - } - } - - func parser(_ parser: XMLParser, foundCharacters string: String) { - if (!currentElement.isEmpty) { - documentFormat = string - } - currentElement = "" - } -} diff --git a/MoppApp/MoppApp/ContainerActions.swift b/MoppApp/MoppApp/ContainerActions.swift index 137fe2530..4b201bd18 100644 --- a/MoppApp/MoppApp/ContainerActions.swift +++ b/MoppApp/MoppApp/ContainerActions.swift @@ -179,28 +179,23 @@ extension ContainerActions where Self: UIViewController { printLog("Unable to delete contents of Documents/Inbox directory: \(error.localizedDescription)") } } else { - let containerViewController = CryptoContainerViewController.instantiate() - let container = CryptoContainer(filename: fileName as NSString, filePath: newFilePath as NSString) - - MoppLibCryptoActions.parseCdocInfo( - newFilePath as String?, - success: { cdocInfo in - container.addressees = cdocInfo.addressees as? [Addressee] ?? [] - container.dataFiles = cdocInfo.dataFiles - containerViewController.containerPath = newFilePath - containerViewController.state = .opened - containerViewController.container = container - containerViewController.isEncrypted = true - landingViewController.importProgressViewController.dismissRecursively(animated: false, completion: { - navController?.pushViewController(containerViewController, animated: true) - }) - }, - failure: { _ in - DispatchQueue.main.async { - failure(nil) + Task(priority: .background) { [newFilePath] in + do { + let cdocInfo = try Decrypt.cdocInfo(newFilePath) + await MainActor.run { [newFilePath] in + let containerViewController = CryptoContainerViewController.instantiate() + containerViewController.containerPath = newFilePath + containerViewController.state = .opened + containerViewController.container = CryptoContainer(filename: fileName, filePath: newFilePath, cdocInfo: cdocInfo) + containerViewController.isEncrypted = true + landingViewController.importProgressViewController.dismissRecursively(animated: false) { + navController?.pushViewController(containerViewController, animated: true) + } } + } catch { + await MainActor.run { failure(error as NSError) } } - ) + } } url.stopAccessingSecurityScopedResource() } @@ -277,18 +272,14 @@ extension ContainerActions where Self: UIViewController { } else { let containerViewController = topSigningViewController as? CryptoContainerViewController dataFilePaths.forEach { - let filename = ($0 as NSString).lastPathComponent as NSString + let filename = ($0 as NSString).lastPathComponent if isDuplicatedFilename(container: (containerViewController?.container)!, filename: filename) { DispatchQueue.main.async { self.infoAlert(message: L(.containerDetailsFileAlreadyExists)) } return } - let dataFile = CryptoDataFile.init() - dataFile.filename = filename as String? - dataFile.filePath = $0 - - containerViewController?.container.dataFiles.append(dataFile) + containerViewController?.container.dataFiles.append(CryptoDataFile(filename: filename, filePath: $0)) } landingViewController.importProgressViewController.dismissRecursively(animated: false, completion: { @@ -312,8 +303,8 @@ extension ContainerActions where Self: UIViewController { } } - private func isDuplicatedFilename(container: CryptoContainer, filename: NSString) -> Bool { - container.dataFiles.contains { $0.filename as NSString == filename } + private func isDuplicatedFilename(container: CryptoContainer, filename: String) -> Bool { + container.dataFiles.contains { $0.filename == filename } } func createNewContainer(with url: URL, dataFilePaths: [String], isEmptyFileImported: Bool, startSigningWhenCreated: Bool = false, cleanUpDataFilesInDocumentsFolder: Bool = true) { @@ -387,14 +378,12 @@ extension ContainerActions where Self: UIViewController { } } else { let containerViewController = CryptoContainerViewController.instantiate() - let container = CryptoContainer(filename: containerFilename as NSString, filePath: containerPath as NSString) + let container = CryptoContainer(filename: containerFilename , filePath: containerPath) containerViewController.containerPath = containerPath for dataFilePath in containerFilePaths { - let dataFile = CryptoDataFile.init() - dataFile.filename = FileUtil.getFileName(currentFileName: (dataFilePath as NSString).lastPathComponent) - dataFile.filePath = dataFilePath - container.dataFiles.append(dataFile) + container.dataFiles.append(CryptoDataFile( + filename: FileUtil.getFileName(currentFileName: (dataFilePath as NSString).lastPathComponent), filePath: dataFilePath)) } containerViewController.container = container diff --git a/MoppApp/MoppApp/ContainerViewController.swift b/MoppApp/MoppApp/ContainerViewController.swift index 6869878ba..3d907f294 100644 --- a/MoppApp/MoppApp/ContainerViewController.swift +++ b/MoppApp/MoppApp/ContainerViewController.swift @@ -45,7 +45,7 @@ protocol SigningContainerViewControllerDelegate: AnyObject { protocol CryptoContainerViewControllerDelegate: AnyObject { func addAddressees() - func getAddressee(index: Int) -> Any + func getAddressee(index: Int) -> Addressee func getAddresseeCount() -> Int func removeSelectedAddressee(index: Int) func getContainer() -> CryptoContainer @@ -656,7 +656,7 @@ extension ContainerViewController : UITableViewDataSource { cell.delegate = self let isStatePreviewOrOpened = state == .opened || state == .preview let isRemoveButtonHidden = !isAsicContainer && isStatePreviewOrOpened - cell.populate(addressee: cryptoContainerViewDelegate.getAddressee(index: indexPath.row) as! Addressee, + cell.populate(addressee: cryptoContainerViewDelegate.getAddressee(index: indexPath.row), index: row, showRemoveButton: !isRemoveButtonHidden) cell.accessibilityUserInputLabels = [""] @@ -873,8 +873,8 @@ extension ContainerViewController : ContainerHeaderDelegate { printLog("Failed to change cdoc file properties") return self.infoAlert(message: L(.containerErrorMessageFailedContainerNameChange)) } - cryptoContainer.filename = newContainerPath.lastPathComponent as NSString - cryptoContainer.filePath = newContainerPath.path as NSString + cryptoContainer.filename = newContainerPath.lastPathComponent + cryptoContainer.filePath = newContainerPath.path } printLog("File renaming successful") diff --git a/MoppApp/MoppApp/CryptoActions.swift b/MoppApp/MoppApp/CryptoActions.swift index 24fd89f38..393c11cb6 100644 --- a/MoppApp/MoppApp/CryptoActions.swift +++ b/MoppApp/MoppApp/CryptoActions.swift @@ -20,8 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ + import Foundation -import CryptoLib protocol CryptoActions { func startEncryptingProcess() @@ -35,11 +35,13 @@ extension CryptoActions where Self: CryptoContainerViewController { return self.infoAlert(message: L(.cryptoNoAddresseesWarning)) } Task.detached { [weak self] in - let result = Encrypt.encryptFile(container.filePath as String, with: container.dataFiles, with: container.addressees) + do { + try await Encrypt.encryptFile(container.filePath, with: container.dataFiles, with: container.addressees) + } catch { + await self?.infoAlert(message: L(.cryptoEncryptionErrorText)) + } guard let self else { return } await MainActor.run { - guard result else { return self.infoAlert(message: L(.cryptoEncryptionErrorText)) } - self.isCreated = false self.isForPreview = false self.isEncrypted = true @@ -69,7 +71,7 @@ extension CryptoActions where Self: CryptoContainerViewController { } extension CryptoContainerViewController : IdCardDecryptViewControllerDelegate { - + func idCardDecryptDidFinished(success: Bool, dataFiles: [String:Data], error: Error?) { dismiss(animated: false) guard success else { @@ -85,10 +87,7 @@ extension CryptoContainerViewController : IdCardDecryptViewControllerDelegate { guard let destinationPath = MoppFileManager.shared.tempFilePath(withFileName: filename) else { return infoAlert(message: L(.decryptionErrorMessage)) } - let cryptoDataFile = CryptoDataFile() - cryptoDataFile.filename = filename - cryptoDataFile.filePath = destinationPath - container.dataFiles.append(cryptoDataFile) + container.dataFiles.append(CryptoDataFile(filename: filename, filePath: destinationPath)) MoppFileManager.shared.createFile(atPath: destinationPath, contents: data) } diff --git a/MoppApp/MoppApp/CryptoContainer.swift b/MoppApp/MoppApp/CryptoContainer.swift index 67c777322..7770f8c94 100644 --- a/MoppApp/MoppApp/CryptoContainer.swift +++ b/MoppApp/MoppApp/CryptoContainer.swift @@ -21,20 +21,18 @@ * */ -import Foundation -import CryptoLib - class CryptoContainer { - - var filename: NSString! - var filePath: NSString! - var dataFiles: [CryptoDataFile] = [] - var addressees: [Addressee] = [] - - init(filename: NSString, filePath: NSString){ + + var filename: String + var filePath: String + var dataFiles: [CryptoDataFile] + var addressees: [Addressee] + + init(filename: String, filePath: String, cdocInfo: CdocInfo? = nil) { self.filename = filename self.filePath = filePath + self.dataFiles = cdocInfo?.dataFiles ?? [] + self.addressees = cdocInfo?.addressees ?? [] } - } diff --git a/MoppApp/MoppApp/CryptoContainerViewController.swift b/MoppApp/MoppApp/CryptoContainerViewController.swift index 13a51fae8..51c1a7448 100644 --- a/MoppApp/MoppApp/CryptoContainerViewController.swift +++ b/MoppApp/MoppApp/CryptoContainerViewController.swift @@ -21,9 +21,6 @@ * */ -import UIKit -import CryptoLib - class CryptoContainerViewController : ContainerViewController, CryptoActions { var container: CryptoContainer! @@ -80,7 +77,7 @@ extension CryptoContainerViewController : CryptoContainerViewControllerDelegate reloadCryptoData() } - func getAddressee(index: Int) -> Any { + func getAddressee(index: Int) -> Addressee { return container.addressees[index] } @@ -183,13 +180,11 @@ extension CryptoContainerViewController : ContainerViewControllerDelegate { } func getDataFileDisplayName(index: Int) -> String? { - guard let dataFile = (container.dataFiles[index] as? CryptoDataFile) else { - return nil - } + let dataFile = container.dataFiles[index] if dataFile.filePath == nil { return dataFile.filename } - return (dataFile.filePath as NSString).lastPathComponent + return (dataFile.filePath! as NSString).lastPathComponent } func getContainer() -> MoppLibContainer { @@ -208,27 +203,21 @@ extension CryptoContainerViewController : ContainerViewControllerDelegate { if state != .loading { return } if container == nil { - let filePath = containerPath as NSString - let container = CryptoContainer(filename: filePath.lastPathComponent as NSString, filePath: filePath) - MoppLibCryptoActions.parseCdocInfo( - filePath as String?, - success: { cdocInfo in - container.addressees = cdocInfo.addressees as? [Addressee] ?? [] - container.dataFiles = cdocInfo.dataFiles - self.containerPath = filePath as String? - self.state = .opened - - self.container = container - self.isEncrypted = true - self.reloadCryptoData() - }, - failure: { _ in - DispatchQueue.main.async { - self.infoAlert(message: L(.fileImportOpenExistingFailedAlertMessage, [filePath.lastPathComponent])) + if let filePath = containerPath as? NSString { + Task(priority: .background) { [weak self] in + let cdocInfo = try? Decrypt.cdocInfo(filePath as String) + await MainActor.run { + guard let self else { return } + guard cdocInfo != nil else { + return self.infoAlert(message: L(.fileImportOpenExistingFailedAlertMessage, [filePath.lastPathComponent])) + } + self.state = .opened + self.container = CryptoContainer(filename: filePath.lastPathComponent, filePath: filePath as String, cdocInfo: cdocInfo) + self.isEncrypted = true + self.reloadCryptoData() } } - ) - + } } self.notifications = [] self.updateState(self.isCreated ? .created : .opened) @@ -239,7 +228,7 @@ extension CryptoContainerViewController : ContainerViewControllerDelegate { } func getDataFileRelativePath(index: Int) -> String { - return (container.dataFiles[index] as! CryptoDataFile).filename! as String + return container.dataFiles[index].filename } func isContainerEmpty() -> Bool { diff --git a/MoppApp/MoppApp/IdCardViewController.swift b/MoppApp/MoppApp/IdCardViewController.swift index c02eec556..d1ad7e0ce 100644 --- a/MoppApp/MoppApp/IdCardViewController.swift +++ b/MoppApp/MoppApp/IdCardViewController.swift @@ -256,7 +256,7 @@ class IdCardViewController : MoppViewController { self.titleLabel.text = L(.nfcCertExpired) pinHidden = true } else if self.isActionDecryption, let cert = self.cert, - !self.addressees.contains(where: { $0.cert == cert }) { + !self.addressees.contains(where: { $0.data == cert }) { self.titleLabel.text = L(.decryptionWrongCard) pinHidden = true } else { @@ -378,7 +378,7 @@ class IdCardViewController : MoppViewController { } Task.detached(priority: .background) { [weak self] in do { - let response = try Decrypt.decryptFile(containerPath, with: SmartToken(card: cardCommands, pin1: pin, cert: cert)) + let response = try await Decrypt.decryptFile(containerPath, with: SmartToken(card: cardCommands, pin1: pin, cert: cert)) guard response.count > 0 else { throw MoppLibError.Code.general } guard let self else { return } await MainActor.run { diff --git a/MoppApp/MoppApp/MimeTypeExtractor.swift b/MoppApp/MoppApp/MimeTypeExtractor.swift index 23e971eb5..395ec2a1c 100644 --- a/MoppApp/MoppApp/MimeTypeExtractor.swift +++ b/MoppApp/MoppApp/MimeTypeExtractor.swift @@ -138,6 +138,9 @@ class MimeTypeExtractor { } public static func findDuplicateFilenames(in filePath: URL) -> [String] { + guard filePath.pathExtension.isAsicContainerExtension else { + return [] + } var filenames = Set() var duplicateFilenames = Set() diff --git a/MoppApp/MoppApp/MoppApp-Bridging-Header.h b/MoppApp/MoppApp/MoppApp-Bridging-Header.h index 236d6c23c..5f03c912b 100644 --- a/MoppApp/MoppApp/MoppApp-Bridging-Header.h +++ b/MoppApp/MoppApp/MoppApp-Bridging-Header.h @@ -3,5 +3,5 @@ // #import -#import +#import #import diff --git a/MoppApp/MoppApp/MoppApp.swift b/MoppApp/MoppApp/MoppApp.swift index 79c0760ad..28c524487 100644 --- a/MoppApp/MoppApp/MoppApp.swift +++ b/MoppApp/MoppApp/MoppApp.swift @@ -34,8 +34,6 @@ class MoppApp: UIApplication, URLSessionDelegate, URLSessionDownloadDelegate { var tempUrl: URL? var downloadCompletion: (() -> Void)? = nil var window: UIWindow? - var currentElement:String = "" - var documentFormat:String = "" var downloadTask: URLSessionTask? var isInvalidFileInList: Bool = false @@ -521,14 +519,8 @@ class MoppApp: UIApplication, URLSessionDelegate, URLSessionDownloadDelegate { } func isXmlExtensionFileCdoc(with url: URL) -> Bool { - let parser = XMLParser(contentsOf: url) - parser?.delegate = self; - parser?.parse() - if documentFormat.hasPrefix("ENCDOC-XML|1.") { - documentFormat = "" - return true - } - return false + guard let cdocInfo = try? CdocInfo(cdoc1Path: url.path) else { return false } + return cdocInfo.format.hasPrefix("ENCDOC-XML|1.") } func convertViewToImage(with view: UIView) -> UIImage? { diff --git a/MoppApp/MoppApp/MyeIDInfoManager.swift b/MoppApp/MoppApp/MyeIDInfoManager.swift index afd6c5c10..d1b444115 100644 --- a/MoppApp/MoppApp/MyeIDInfoManager.swift +++ b/MoppApp/MoppApp/MyeIDInfoManager.swift @@ -446,7 +446,7 @@ extension MyeIDInfoManager { } } -extension X509Certificate.CertType { +extension CertType { var organizationDisplayString: String { switch self { case .IDCardType: diff --git a/MoppApp/MoppApp/RecentContainersViewController.swift b/MoppApp/MoppApp/RecentContainersViewController.swift index 0f7b20156..8222cf0e8 100644 --- a/MoppApp/MoppApp/RecentContainersViewController.swift +++ b/MoppApp/MoppApp/RecentContainersViewController.swift @@ -21,8 +21,6 @@ * */ -import UIKit -import CryptoLib class RecentContainersViewController : MoppModalViewController { var requestCloseSearch: (() -> Void) = {} @IBOutlet weak var tableView: UITableView! @@ -197,21 +195,18 @@ extension RecentContainersViewController : UITableViewDelegate { } guard let path = containerPath else { return } self.closeSearch() - dismiss(animated: true, completion: { + dismiss(animated: true) { let ext = (filename as NSString).pathExtension var navController: UINavigationController = (LandingViewController.shared.viewController(for: .signTab) as? UINavigationController)! - let failure: (_ customMessage: String?) -> Void = { customMessage in + let failure: (_ message: String) -> Void = { message in LandingViewController.shared.importProgressViewController.dismissRecursivelyIfPresented(animated: false, completion: nil) - - let message = customMessage ?? L(.fileImportOpenExistingFailedAlertMessage, [filename]) let alert = UIAlertController( title: L(.fileImportOpenExistingFailedAlertTitle), message: message, preferredStyle: .alert ) alert.addAction(UIAlertAction(title: L(.actionOk), style: .default, handler: nil)) - navController.viewControllers.last!.present(alert, animated: true) } @@ -236,35 +231,25 @@ extension RecentContainersViewController : UITableViewDelegate { self.openContainer(containerPath: path.path, navController: navController, isSendingToSivaAgreed: true) } } else { - var containerViewController: ContainerViewController LandingViewController.shared.containerType = .cdoc - containerViewController = CryptoContainerViewController.instantiate() - containerViewController.containerPath = path.path - - let container = CryptoContainer(filename: path.lastPathComponent as NSString, filePath: path.path as NSString) - - MoppLibCryptoActions.parseCdocInfo( - path.path as String?, - success: { cdocInfo in - let cryptoContainer = (containerViewController as! CryptoContainerViewController) - container.addressees = cdocInfo.addressees - container.dataFiles = cdocInfo.dataFiles - cryptoContainer.containerPath = path.path as String? - cryptoContainer.state = .opened - - cryptoContainer.container = container - cryptoContainer.isEncrypted = true - - navController = (LandingViewController.shared.viewController(for: .cryptoTab) as? UINavigationController)! - navController.pushViewController(cryptoContainer, animated: true) - }, - failure: { _ in - failure(nil) + Task(priority: .background) { + do { + let cdocInfo = try Decrypt.cdocInfo(path.path) + await MainActor.run { + let cryptoContainer = CryptoContainerViewController.instantiate() + cryptoContainer.containerPath = path.path + cryptoContainer.container = CryptoContainer(filename: path.lastPathComponent, filePath: path.path, cdocInfo: cdocInfo) + cryptoContainer.state = .opened + cryptoContainer.isEncrypted = true + navController = (LandingViewController.shared.viewController(for: .cryptoTab) as? UINavigationController)! + navController.pushViewController(cryptoContainer, animated: true) + } + } catch { + await MainActor.run { failure(L(.fileImportOpenExistingFailedAlertMessage, [filename])) } } - ) + } } - - }) + } } } diff --git a/MoppLib/MoppLib.xcodeproj/project.pbxproj b/MoppLib/MoppLib.xcodeproj/project.pbxproj index f7603c53b..adc0d62b9 100644 --- a/MoppLib/MoppLib.xcodeproj/project.pbxproj +++ b/MoppLib/MoppLib.xcodeproj/project.pbxproj @@ -8,8 +8,6 @@ /* Begin PBXBuildFile section */ 39266A5320CFC0F4002E3F23 /* SmartToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39266A5220CFC0F4002E3F23 /* SmartToken.swift */; }; - 399C01E320BC11C20056D7AC /* MoppLibCryptoActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 399C01E220BC11C20056D7AC /* MoppLibCryptoActions.m */; }; - 399C01E620BC17A10056D7AC /* MoppLibCryptoActions.h in Headers */ = {isa = PBXBuildFile; fileRef = 399C01E120BC0EF30056D7AC /* MoppLibCryptoActions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 39DFDA6320C81F5D00D0D134 /* CryptoLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 399C01E420BC13320056D7AC /* CryptoLib.framework */; }; 4E0053842D7DEE8B00B1AFE5 /* CardCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5463DA4A1E12927A008A1714 /* CardCommands.swift */; }; 4E098E8D2DCE2CCA001C012D /* BigInt in Frameworks */ = {isa = PBXBuildFile; productRef = 4E098E8C2DCE2CCA001C012D /* BigInt */; }; @@ -43,8 +41,6 @@ /* Begin PBXFileReference section */ 39266A5220CFC0F4002E3F23 /* SmartToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartToken.swift; sourceTree = ""; }; - 399C01E120BC0EF30056D7AC /* MoppLibCryptoActions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoppLibCryptoActions.h; sourceTree = ""; }; - 399C01E220BC11C20056D7AC /* MoppLibCryptoActions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MoppLibCryptoActions.m; sourceTree = ""; }; 399C01E420BC13320056D7AC /* CryptoLib.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoLib.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4E23C1722DCE1A7100FA4F3F /* CardReaderNFC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderNFC.swift; sourceTree = ""; }; 4E63A77A2AEA7C5A00CEE392 /* digidocpp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = digidocpp.framework; path = "$(DIGIDOCPP_PATH)/lib/digidocpp.framework"; sourceTree = ""; }; @@ -180,8 +176,6 @@ E4250CEA1E09695100530370 /* MoppLib.h */, 54D164751E9269C50069C725 /* MoppLibContainerActions.h */, 54D164761E9269C50069C725 /* MoppLibContainerActions.mm */, - 399C01E120BC0EF30056D7AC /* MoppLibCryptoActions.h */, - 399C01E220BC11C20056D7AC /* MoppLibCryptoActions.m */, 54DC0E001E0D48C900C62B3D /* MoppLibError.swift */, 54E1DB5B1E44A9060060A250 /* MoppLibManager.swift */, 39266A5220CFC0F4002E3F23 /* SmartToken.swift */, @@ -199,7 +193,6 @@ C5AAAF8620CAA3F00087D6DA /* winscard.h in Headers */, C5AAAF8820CAA4240087D6DA /* wintypes.h in Headers */, C5AAAF8A20CAA4790087D6DA /* ft301u.h in Headers */, - 399C01E620BC17A10056D7AC /* MoppLibCryptoActions.h in Headers */, 54D164771E9269C50069C725 /* MoppLibContainerActions.h in Headers */, E4250CEC1E09695100530370 /* MoppLib.h in Headers */, C5AAAF8420CAA3D00087D6DA /* ReaderInterface.h in Headers */, @@ -238,7 +231,7 @@ TargetAttributes = { E4250CE61E09695100530370 = { CreatedOnToolsVersion = 8.0; - LastSwiftMigration = 0820; + LastSwiftMigration = 1620; }; }; }; @@ -274,7 +267,6 @@ 54E1DB5D1E44A9060060A250 /* MoppLibManager.swift in Sources */, E42B08B61E1F0B3B00EA24A3 /* MoppLibContainer.swift in Sources */, 4EAE02FF2E02A2590061C4EB /* MoppLibSignature.swift in Sources */, - 399C01E320BC11C20056D7AC /* MoppLibCryptoActions.m in Sources */, C5E41C5E2180602B00D79B54 /* Idemia.swift in Sources */, 39266A5320CFC0F4002E3F23 /* SmartToken.swift in Sources */, C54EA732204D5E860039AC78 /* CardReaderiR301.swift in Sources */, @@ -294,6 +286,7 @@ E4250CED1E09695100530370 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -321,7 +314,6 @@ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; @@ -349,10 +341,12 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -360,6 +354,7 @@ E4250CEE1E09695100530370 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -387,7 +382,6 @@ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; @@ -408,10 +402,12 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; + TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; }; diff --git a/MoppLib/MoppLib/MoppLib.h b/MoppLib/MoppLib/MoppLib.h index 3138e22a5..08c2b0c18 100644 --- a/MoppLib/MoppLib/MoppLib.h +++ b/MoppLib/MoppLib/MoppLib.h @@ -31,4 +31,3 @@ FOUNDATION_EXPORT const unsigned char MoppLibVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import #import -#import diff --git a/MoppLib/MoppLib/MoppLibCryptoActions.h b/MoppLib/MoppLib/MoppLibCryptoActions.h deleted file mode 100644 index 0d99afee8..000000000 --- a/MoppLib/MoppLib/MoppLibCryptoActions.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// MoppLibCryptoActions.h -// MoppLib -// -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import - -@class CdocInfo; -@protocol AbstractSmartToken; - -typedef void (^FailureBlock)(NSError *error); -typedef void (^CdocContainerBlock)(CdocInfo * _Nonnull cdocInfo); - -@interface MoppLibCryptoActions : NSObject - -/** - * Parse and get info of CDOC container. - * - * @param fullPath Full path of CDOC container file. - * @param success Block to be called on successful completion of action. Includes CDOC container info as CdocContainerBlock. - * @param failure Block to be called when action fails. Includes error. - */ -+ (void)parseCdocInfo:(NSString *)fullPath success:(CdocContainerBlock)success failure:(FailureBlock)failure; - -@end diff --git a/MoppLib/MoppLib/MoppLibCryptoActions.m b/MoppLib/MoppLib/MoppLibCryptoActions.m deleted file mode 100644 index a7c8051bf..000000000 --- a/MoppLib/MoppLib/MoppLibCryptoActions.m +++ /dev/null @@ -1,45 +0,0 @@ -// -// MoppLibCryptoActions.m -// MoppLib -// -/* - * Copyright 2017 - 2024 Riigi Infosüsteemi Amet - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#import "MoppLibCryptoActions.h" - -#import -#import - -@implementation MoppLibCryptoActions - -+ (void)parseCdocInfo:(NSString *)fullPath success:(CdocContainerBlock)success failure:(FailureBlock)failure { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSError *error = nil; - CdocParser *cdocParser = [CdocParser new]; - CdocInfo *response = [cdocParser parseCdocInfo:fullPath]; - if (response.addressees == nil || response.dataFiles == nil) { - error = [MoppLibError error:MoppLibErrorCodeGeneral]; - } - dispatch_async(dispatch_get_main_queue(), ^{ - error == nil ? success(response) : failure(error); - }); - }); -} - -@end diff --git a/MoppLib/MoppLib/SmartToken.swift b/MoppLib/MoppLib/SmartToken.swift index 22e7a6625..8410f8113 100644 --- a/MoppLib/MoppLib/SmartToken.swift +++ b/MoppLib/MoppLib/SmartToken.swift @@ -59,7 +59,7 @@ public class SmartToken: AbstractSmartToken { self.cert = cert } - public func getCertificate() throws -> Data { + public func getCertificate() async throws -> Data { cert } diff --git a/codemagic.yaml b/codemagic.yaml index 031720f16..2384dd749 100644 --- a/codemagic.yaml +++ b/codemagic.yaml @@ -62,7 +62,7 @@ workflows: scripts: - name: Setup dependencies script: | - brew install swift-sh + brew install swift-sh flatbuffers - *get_app_version - *get_google_services_plist - name: "Setup config and TSL files" @@ -212,7 +212,7 @@ workflows: scripts: - name: Setup dependencies script: | - brew install swift-sh + brew install swift-sh flatbuffers - *get_app_version - *get_google_services_plist - name: "Setup config and TSL files"