From 526cf37eb04905c76c5e1a1365f2dfcdde853582 Mon Sep 17 00:00:00 2001 From: Marten Rebane <54431068+martenrebane@users.noreply.github.com> Date: Tue, 5 Mar 2024 10:20:25 +0200 Subject: [PATCH 1/4] Fixed opening CAdES files --- MoppApp/MoppApp/ContainerActions.swift | 14 ++-- MoppApp/MoppApp/ContainerViewController.swift | 4 +- MoppApp/MoppApp/MimeTypeExtractor.swift | 76 ++++++++++++++----- MoppApp/MoppApp/PreviewActions.swift | 5 ++ .../RecentContainersViewController.swift | 5 +- MoppApp/MoppApp/SivaUtil.swift | 17 ++++- MoppLib/MoppLib.xcodeproj/project.pbxproj | 8 ++ MoppLib/MoppLib/MoppLibDigidocManager.mm | 54 +++++++++++-- .../MoppLib/MoppLibDigidocValidateOnline.h | 33 ++++++++ .../MoppLib/MoppLibDigidocValidateOnline.m | 39 ++++++++++ MoppLib/MoppLib/PublicInterface/MoppLib.h | 1 + 11 files changed, 221 insertions(+), 35 deletions(-) create mode 100644 MoppLib/MoppLib/MoppLibDigidocValidateOnline.h create mode 100644 MoppLib/MoppLib/MoppLibDigidocValidateOnline.m diff --git a/MoppApp/MoppApp/ContainerActions.swift b/MoppApp/MoppApp/ContainerActions.swift index db9efa20e..b47103158 100644 --- a/MoppApp/MoppApp/ContainerActions.swift +++ b/MoppApp/MoppApp/ContainerActions.swift @@ -82,16 +82,19 @@ extension ContainerActions where Self: UIViewController { let isAsicOrPadesContainer = (ext.isAsicContainerExtension || ext == ContainerFormatPDF) && landingViewController.containerType == .asic let isCdocContainer = ext.isCdocContainerExtension && landingViewController.containerType == .cdoc - if (isAsicOrPadesContainer || isCdocContainer) && urls.count == 1 { - if (urls.first?.pathExtension == "asics" || urls.first?.pathExtension == "scs") || SignatureUtil.isCades(signatures: SignatureUtil.getSignatures(filePath: urls.first!)) { + if (isAsicOrPadesContainer || isCdocContainer) && urls.count == 1 { + SiVaUtil.setIsSentToSiva(isSent: false) + + if let firstUrl = urls.first, (firstUrl.pathExtension == "asics" || firstUrl.pathExtension == "scs") || MimeTypeExtractor.isCadesContainer(filePath: firstUrl) { if self?.getTopViewController() is FileImportProgressViewController { self?.dismiss(animated: true, completion: { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in - self?.openExistingContainer(with: urls.first!, cleanup: cleanup, isEmptyFileImported: isEmptyFileImported, isSendingToSivaAgreed: hasAgreed) + self?.openExistingContainer(with: firstUrl, cleanup: cleanup, isEmptyFileImported: isEmptyFileImported, isSendingToSivaAgreed: hasAgreed) } }) } } else { + SiVaUtil.setIsSentToSiva(isSent: true) self?.openExistingContainer(with: urls.first!, cleanup: cleanup, isEmptyFileImported: isEmptyFileImported, isSendingToSivaAgreed: isSendingToSivaAgreed) } } else { @@ -150,8 +153,8 @@ extension ContainerActions where Self: UIViewController { let forbiddenFileExtensions = ["ddoc", "asics", "scs"] let fileURL = URL(fileURLWithPath: newFilePath) let fileExtension = fileURL.pathExtension - let isSignedPDF = SiVaUtil.isDocumentSentToSiVa(fileUrl: fileURL) - if (forbiddenFileExtensions.contains(fileExtension) || isSignedPDF) { + let isSignedPDF = SiVaUtil.isSignedPDF(url: fileURL as CFURL) + if (forbiddenFileExtensions.contains(fileExtension) || isSignedPDF || MimeTypeExtractor.isCadesContainer(filePath: fileURL)) { self.openContainer(url: url, newFilePath: newFilePath, fileName: fileName, landingViewController: landingViewController, navController: navController, isEmptyFileImported: isEmptyFileImported, isSendingToSivaAgreed: isSendingToSivaAgreed) { error in failure(error) } @@ -189,6 +192,7 @@ extension ContainerActions where Self: UIViewController { } func openContainer(url: URL, newFilePath: String, fileName: String, landingViewController: LandingViewController, navController: UINavigationController?, isEmptyFileImported: Bool, isSendingToSivaAgreed: Bool, failure: @escaping ((_ error: NSError?) -> Void)) { + SiVaUtil.setIsSentToSiva(isSent: isSendingToSivaAgreed) MoppLibContainerActions.sharedInstance().openContainer(withPath: newFilePath, success: { (_ container: MoppLibContainer?) -> Void in if container == nil { diff --git a/MoppApp/MoppApp/ContainerViewController.swift b/MoppApp/MoppApp/ContainerViewController.swift index 4c3358b5e..7aa427eec 100644 --- a/MoppApp/MoppApp/ContainerViewController.swift +++ b/MoppApp/MoppApp/ContainerViewController.swift @@ -675,7 +675,8 @@ extension ContainerViewController : UITableViewDataSource { if signingContainerViewDelegate.getTimestampTokensCount() >= indexPath.row { timestampToken = signingContainerViewDelegate.getTimestampToken(index: indexPath.row) as? MoppLibSignature ?? MoppLibSignature() - if (containerViewDelegate.getDataFileCount() == 1 && isSendingToSivaAgreed && !isLoadingNestedAsicsDone) { + if (containerViewDelegate.getDataFileCount() == 1 && isSendingToSivaAgreed && + !isLoadingNestedAsicsDone && !MimeTypeExtractor.isCadesContainer(filePath: URL(fileURLWithPath: containerViewDelegate.getContainerPath()))) { updateState(.loading) let dataFile = containerViewDelegate.getDataFileDisplayName(index: 0) ?? "" let containerFilePath = containerViewDelegate.getContainerPath() @@ -773,6 +774,7 @@ extension ContainerViewController : UITableViewDataSource { if pathExtension == "asics" || pathExtension == "scs" { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in if hasAgreed { + SiVaUtil.setIsSentToSiva(isSent: hasAgreed) self.openNestedContainer(containerFilePath: containerFilePath, dataFile: dataFile, destinationPath: destinationPath) return } else { diff --git a/MoppApp/MoppApp/MimeTypeExtractor.swift b/MoppApp/MoppApp/MimeTypeExtractor.swift index 8a572d3bc..a1bbc7876 100644 --- a/MoppApp/MoppApp/MimeTypeExtractor.swift +++ b/MoppApp/MoppApp/MimeTypeExtractor.swift @@ -30,14 +30,34 @@ class MimeTypeExtractor { private static let DEFAULT_MIMETYPE = "application/octet-stream" + // Check if file is zip format + private static func isZipFile(filePath: URL) -> Bool { + guard let fileHandle = FileHandle(forReadingAtPath: filePath.path) else { return false } + let fileData = fileHandle.readData(ofLength: 4) + let isZip = fileData.starts(with: [0x50, 0x4b, 0x03, 0x04]) + do { + try fileHandle.close() + } catch (let zipError) { + printLog("Unable to close zip file: \(zipError.localizedDescription)") + } + return isZip + } + + public static func isCadesContainer(filePath: URL) -> Bool { + if isZipFile(filePath: filePath) { + return containerHasSignatureFiles(filePath: filePath) + } + + return false + } + public static func getMimeTypeFromContainer(filePath: URL) -> String { + let isCades = isCadesContainer(filePath: filePath) + var mimetype: String = "" - guard let fileHandle = FileHandle(forReadingAtPath: filePath.path) else { return "" } - let fileData = fileHandle.readData(ofLength: 4) - // Check if file is zip format - if fileData.starts(with: [0x50, 0x4b, 0x03, 0x04]) { + if isZipFile(filePath: filePath) { guard let unzippedFile = unZipFile(filePath: filePath, fileName: "mimetype") else { return mimetype } @@ -48,7 +68,6 @@ class MimeTypeExtractor { removeUnzippedFolder(folderPath: unzippedFolder) } - fileHandle.closeFile() if isDdoc(url: filePath) { return ContainerFormatDdocMimetype @@ -110,25 +129,46 @@ class MimeTypeExtractor { } return fileExtension + } + + private static func containerHasSignatureFiles(filePath: URL) -> Bool { + do { + let archive = try Archive(url: filePath, accessMode: .read) + + for entry in archive { + let entryUrl = URL(fileURLWithPath: entry.path) + if entryUrl.lastPathComponent.contains("p7s") { + return true + } + } + } catch (let archiveError) { + printLog("Unable to open archive: \(archiveError.localizedDescription)") + return false + } + return false } private static func unZipFile(filePath: URL, fileName: String) -> URL? { let outputPath = MoppFileManager.shared.tempCacheDirectoryPath().appendingPathComponent(filePath.lastPathComponent).deletingPathExtension() - guard let archive = Archive(url: filePath, accessMode: .read) else { - return nil - } - guard let fileInArchive = archive[fileName] else { - return nil - } - var destinationLocation = URL(fileURLWithPath: outputPath.path) - destinationLocation.appendPathComponent("mimetype") + do { - printLog("Extracting file: \(fileName)") - _ = try archive.extract(fileInArchive, to: destinationLocation) - return destinationLocation - } catch { - printLog("Unable to extract file \(fileInArchive). Error: \(error.localizedDescription)") + let archive = try Archive(url: filePath, accessMode: .read) + guard let fileInArchive = archive[fileName] else { + return nil + } + var destinationLocation = URL(fileURLWithPath: outputPath.path) + destinationLocation.appendPathComponent("extractedFile") + do { + printLog("Extracting file: \(fileName) to \(destinationLocation.path)") + _ = try archive.extract(fileInArchive, to: destinationLocation) + return destinationLocation + } catch { + printLog("Unable to extract file \(fileInArchive). Error: \(error.localizedDescription)") + return nil + } + } catch (let archiveError) { + printLog("Unable to open archive: \(archiveError.localizedDescription)") return nil } } diff --git a/MoppApp/MoppApp/PreviewActions.swift b/MoppApp/MoppApp/PreviewActions.swift index 6bba9e4bc..d0b367030 100644 --- a/MoppApp/MoppApp/PreviewActions.swift +++ b/MoppApp/MoppApp/PreviewActions.swift @@ -51,6 +51,7 @@ extension PreviewActions where Self: ContainerViewController { let containerViewController = SigningContainerViewController.instantiate() let destinationPathURL = URL(fileURLWithPath: destinationPath) + SiVaUtil.setIsSentToSiva(isSent: false) if SiVaUtil.isDocumentSentToSiVa(fileUrl: destinationPathURL) { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in if (destinationPathURL.pathExtension == "ddoc" || destinationPathURL.pathExtension == "pdf") && !hasAgreed { @@ -59,6 +60,7 @@ extension PreviewActions where Self: ContainerViewController { openAsicContainerPreviewDocument(containerViewController, isPDF, hasAgreed) } } else { + SiVaUtil.setIsSentToSiva(isSent: true) openAsicContainerPreviewDocument(containerViewController, isPDF, true) } } @@ -100,6 +102,7 @@ extension PreviewActions where Self: ContainerViewController { let fileExtension = URL(fileURLWithPath: filePath).pathExtension.lowercased() + SiVaUtil.setIsSentToSiva(isSent: false) if fileExtension != "pdf" && SiVaUtil.isDocumentSentToSiVa(fileUrl: URL(fileURLWithPath: filePath)) { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in if hasAgreed { @@ -107,6 +110,7 @@ extension PreviewActions where Self: ContainerViewController { } } } else { + SiVaUtil.setIsSentToSiva(isSent: true) openContentPreviewDocument(filePath) } @@ -114,6 +118,7 @@ extension PreviewActions where Self: ContainerViewController { let openPDFPreview: () -> Void = { [weak self] in self?.updateState(.loading) + SiVaUtil.setIsSentToSiva(isSent: false) MoppLibContainerActions.sharedInstance().openContainer( withPath: destinationPath, success: { [weak self] (_ container: MoppLibContainer?) -> Void in diff --git a/MoppApp/MoppApp/RecentContainersViewController.swift b/MoppApp/MoppApp/RecentContainersViewController.swift index c2fe5976a..760724be9 100644 --- a/MoppApp/MoppApp/RecentContainersViewController.swift +++ b/MoppApp/MoppApp/RecentContainersViewController.swift @@ -210,14 +210,17 @@ extension RecentContainersViewController : UITableViewDelegate { if ext.isAsicContainerExtension || ext.isPdfContainerExtension { let containerPathURL = path + SiVaUtil.setIsSentToSiva(isSent: false) if SiVaUtil.isDocumentSentToSiVa(fileUrl: containerPathURL) || (containerPathURL.pathExtension == "asics" || containerPathURL.pathExtension == "scs") { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in - if (containerPathURL.pathExtension == "ddoc" || containerPathURL.pathExtension == "pdf") && !hasAgreed { + if (containerPathURL.pathExtension == "ddoc" || containerPathURL.pathExtension == "pdf" || + MimeTypeExtractor.isCadesContainer(filePath: containerPathURL)) && !hasAgreed { return } self.openContainer(containerPath: path.path, navController: navController, isSendingToSivaAgreed: hasAgreed) } } else { + SiVaUtil.setIsSentToSiva(isSent: true) self.openContainer(containerPath: path.path, navController: navController, isSendingToSivaAgreed: true) } } else { diff --git a/MoppApp/MoppApp/SivaUtil.swift b/MoppApp/MoppApp/SivaUtil.swift index fab7bece6..4b2b0cbed 100644 --- a/MoppApp/MoppApp/SivaUtil.swift +++ b/MoppApp/MoppApp/SivaUtil.swift @@ -23,25 +23,33 @@ import Foundation import PDFKit +import MoppLib class SiVaUtil { static func isDocumentSentToSiVa(fileUrl: URL?) -> Bool { guard let fileLocation = fileUrl else { return false } + let containerTypes = ["asics", "scs", "ddoc"] let containerType = MimeTypeExtractor.determineContainer(mimetype: MimeTypeExtractor.getMimeTypeFromContainer(filePath: fileLocation), fileExtension: fileLocation.pathExtension).lowercased() if containerType == "pdf" { - return isSignedPDF(url: fileLocation as CFURL) + let isSignedPDF = isSignedPDF(url: fileLocation as CFURL) + return isSignedPDF } - return containerType == "ddoc" || SignatureUtil.isCades(signatures: SignatureUtil.getSignatures(filePath: fileLocation)) + let isCades = MimeTypeExtractor.isCadesContainer(filePath: fileLocation) + let isSentToSiva = containerTypes.contains(containerType) || isCades + + return isSentToSiva } static func displaySendingToSiVaDialog(completionHandler: @escaping (Bool) -> Void) { let alert = UIAlertController(title: L(.sivaSendMessage).removeFirstLinkFromMessage(), message: nil, preferredStyle: .alert) alert.addAction(UIAlertAction(title: L(.actionYes).uppercased(), style: .default, handler: { (_ action: UIAlertAction) in + setIsSentToSiva(isSent: true) completionHandler(true) })) alert.addAction(UIAlertAction(title: L(.actionAbort), style: .default, handler: {(_ action: UIAlertAction) -> Void in + setIsSentToSiva(isSent: false) completionHandler(false) })) if let linkInUrl: String = L(.sivaSendMessage).getFirstLinkInMessage() { @@ -112,4 +120,9 @@ class SiVaUtil { return false } + + static func setIsSentToSiva(isSent: Bool) { + let validateOnlineInstance = MoppLibDigidocValidateOnline.sharedInstance() + validateOnlineInstance?.validateOnline = isSent + } } diff --git a/MoppLib/MoppLib.xcodeproj/project.pbxproj b/MoppLib/MoppLib.xcodeproj/project.pbxproj index 6855ab375..a34e2ce6e 100644 --- a/MoppLib/MoppLib.xcodeproj/project.pbxproj +++ b/MoppLib/MoppLib.xcodeproj/project.pbxproj @@ -68,6 +68,8 @@ C5F462A8209727E8001B7D59 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5F462A7209727E8001B7D59 /* CoreBluetooth.framework */; }; C5F974D4217646CD00A167C7 /* TestEnvInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = C5F974D3217646CC00A167C7 /* TestEnvInfo.plist */; }; DF1503872AC5CE32007222B2 /* OCMock in Frameworks */ = {isa = PBXBuildFile; productRef = DF1503862AC5CE32007222B2 /* OCMock */; }; + DF169D5A2B9000F0000DD46C /* MoppLibDigidocValidateOnline.h in Headers */ = {isa = PBXBuildFile; fileRef = DF169D592B9000F0000DD46C /* MoppLibDigidocValidateOnline.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DF169D5C2B90011E000DD46C /* MoppLibDigidocValidateOnline.m in Sources */ = {isa = PBXBuildFile; fileRef = DF169D5B2B90011E000DD46C /* MoppLibDigidocValidateOnline.m */; }; DF1EE2BD234DD20500E37CA8 /* MoppLibCertificateInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DF1EE2BB234DD20500E37CA8 /* MoppLibCertificateInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; DF1EE2BE234DD20500E37CA8 /* MoppLibCertificateInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF1EE2BC234DD20500E37CA8 /* MoppLibCertificateInfo.mm */; }; DF87E9CE292CC79500C2E3F4 /* libdigidocpp_util.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DF87E9CD292CC77C00C2E3F4 /* libdigidocpp_util.a */; }; @@ -178,6 +180,8 @@ C5E41C5C2180602B00D79B54 /* Idemia.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Idemia.m; sourceTree = ""; }; C5F462A7209727E8001B7D59 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = System/Library/Frameworks/CoreBluetooth.framework; sourceTree = SDKROOT; }; C5F974D3217646CC00A167C7 /* TestEnvInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = TestEnvInfo.plist; sourceTree = ""; }; + DF169D592B9000F0000DD46C /* MoppLibDigidocValidateOnline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoppLibDigidocValidateOnline.h; sourceTree = ""; }; + DF169D5B2B90011E000DD46C /* MoppLibDigidocValidateOnline.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MoppLibDigidocValidateOnline.m; sourceTree = ""; }; DF1EE2BB234DD20500E37CA8 /* MoppLibCertificateInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoppLibCertificateInfo.h; sourceTree = ""; }; DF1EE2BC234DD20500E37CA8 /* MoppLibCertificateInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MoppLibCertificateInfo.mm; sourceTree = ""; }; DF87E9CD292CC77C00C2E3F4 /* libdigidocpp_util.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdigidocpp_util.a; path = MoppLib/libdigidocpp/libdigidocpp.iphoneos/lib/libdigidocpp_util.a; sourceTree = ""; }; @@ -440,6 +444,8 @@ E4250CFF1E096CAA00530370 /* test.bdoc */, E4250CF21E096A0500530370 /* libdigidocpp */, C55A20C321762448007BB191 /* mopplib.modulemap */, + DF169D592B9000F0000DD46C /* MoppLibDigidocValidateOnline.h */, + DF169D5B2B90011E000DD46C /* MoppLibDigidocValidateOnline.m */, ); path = MoppLib; sourceTree = ""; @@ -507,6 +513,7 @@ 545CF8411E13F30300B66EE8 /* EstEIDv3_4.h in Headers */, C5AAAF8420CAA3D00087D6DA /* ReaderInterface.h in Headers */, 54DC0DC51E0BCC2A00C62B3D /* CardReaderWrapper.h in Headers */, + DF169D5A2B9000F0000DD46C /* MoppLibDigidocValidateOnline.h in Headers */, C5E41C5D2180602B00D79B54 /* Idemia.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -645,6 +652,7 @@ 54D1647C1E926AAB0069C725 /* MoppLibCardActions.m in Sources */, E42B08CA1E1F11C100EA24A3 /* MoppLibSignature.m in Sources */, 54DC0DCA1E0BCCEF00C62B3D /* MoppLibConstants.m in Sources */, + DF169D5C2B90011E000DD46C /* MoppLibDigidocValidateOnline.m in Sources */, 54DC0DF51E0BEF2A00C62B3D /* NSString+Additions.m in Sources */, 540CB2211E1CDCED00FE18A3 /* MoppLibCertificate.mm in Sources */, 399C01E320BC11C20056D7AC /* MoppLibCryptoActions.m in Sources */, diff --git a/MoppLib/MoppLib/MoppLibDigidocManager.mm b/MoppLib/MoppLib/MoppLibDigidocManager.mm index e56e2350a..5bbd3f350 100644 --- a/MoppLib/MoppLib/MoppLibDigidocManager.mm +++ b/MoppLib/MoppLib/MoppLibDigidocManager.mm @@ -42,6 +42,7 @@ #import #import #import "MoppLibGlobals.h" +#import "MoppLibDigidocValidateOnline.h" #include @@ -247,6 +248,19 @@ int logLevel() const override { digidoc::X509Cert _cert; }; +class MoppLibDigidocContainerOpenCB: public digidoc::ContainerOpenCB { +private: + bool validate; + +public: + MoppLibDigidocContainerOpenCB(bool validate) + : validate(validate) {} + + virtual bool validateOnline() const { + return validate; + } +}; + @interface MoppLibDigidocManager () - (MoppLibSignatureStatus)determineSignatureStatus:(int) status; @@ -425,7 +439,10 @@ + (NSString *)prepareSignature:(NSData *)cert containerPath:(NSString *)containe signature = NULL; try { - docContainer = digidoc::Container::openPtr(containerPath.UTF8String); + MoppLibDigidocValidateOnline *validateOnlineInstance = [MoppLibDigidocValidateOnline sharedInstance]; + BOOL isValidatedOnline = validateOnlineInstance.validateOnline; + MoppLibDigidocContainerOpenCB cb(isValidatedOnline); + docContainer = digidoc::Container::openPtr(containerPath.UTF8String, &cb); } catch(const digidoc::Exception &e) { parseException(e); return nil; @@ -475,7 +492,10 @@ - (MoppLibContainer *)getContainerWithPath:(NSString *)containerPath error:(NSEr std::unique_ptr doc; try { - doc = digidoc::Container::openPtr(containerPath.UTF8String); + MoppLibDigidocValidateOnline *validateOnlineInstance = [MoppLibDigidocValidateOnline sharedInstance]; + BOOL isValidatedOnline = validateOnlineInstance.validateOnline; + MoppLibDigidocContainerOpenCB cb(isValidatedOnline); + doc = digidoc::Container::openPtr(containerPath.UTF8String, &cb); } catch(const digidoc::Exception &e) { parseException(e); @@ -706,7 +726,10 @@ - (MoppLibContainer *)addDataFilesToContainerWithPath:(NSString *)containerPath std::unique_ptr container; try { - container = digidoc::Container::openPtr(containerPath.UTF8String); + MoppLibDigidocValidateOnline *validateOnlineInstance = [MoppLibDigidocValidateOnline sharedInstance]; + BOOL isValidatedOnline = validateOnlineInstance.validateOnline; + MoppLibDigidocContainerOpenCB cb(isValidatedOnline); + container = digidoc::Container::openPtr(containerPath.UTF8String, &cb); for (NSString *dataFilePath in dataFilePaths) { [self addDataFileToContainer:container.get() withDataFilePath:dataFilePath error: error]; @@ -745,7 +768,10 @@ - (void)addDataFileToContainer:(digidoc::Container *)container withDataFilePath: - (MoppLibContainer *)removeDataFileFromContainerWithPath:(NSString *)containerPath atIndex:(NSUInteger)dataFileIndex error:(NSError **)error { std::unique_ptr container; try { - container = digidoc::Container::openPtr(containerPath.UTF8String); + MoppLibDigidocValidateOnline *validateOnlineInstance = [MoppLibDigidocValidateOnline sharedInstance]; + BOOL isValidatedOnline = validateOnlineInstance.validateOnline; + MoppLibDigidocContainerOpenCB cb(isValidatedOnline); + container = digidoc::Container::openPtr(containerPath.UTF8String, &cb); container->removeDataFile((int)dataFileIndex); try { @@ -805,7 +831,10 @@ - (void)addSignature:(NSString *)containerPath pin2:(NSString *)pin2 cert:(NSDat std::unique_ptr managedContainer; // Load the container - managedContainer = digidoc::Container::openPtr(containerPath.UTF8String); + MoppLibDigidocValidateOnline *validateOnlineInstance = [MoppLibDigidocValidateOnline sharedInstance]; + BOOL isValidatedOnline = validateOnlineInstance.validateOnline; + MoppLibDigidocContainerOpenCB cb(isValidatedOnline); + managedContainer = digidoc::Container::openPtr(containerPath.UTF8String, &cb); // Check if key type in certificate supports ECC algorithm @@ -886,7 +915,10 @@ - (void)addSignature:(NSString *)containerPath pin2:(NSString *)pin2 cert:(NSDat } - (MoppLibContainer *)removeSignature:(MoppLibSignature *)moppSignature fromContainerWithPath:(NSString *)containerPath error:(NSError **)error { - std::unique_ptr doc = digidoc::Container::openPtr(containerPath.UTF8String); + MoppLibDigidocValidateOnline *validateOnlineInstance = [MoppLibDigidocValidateOnline sharedInstance]; + BOOL isValidatedOnline = validateOnlineInstance.validateOnline; + MoppLibDigidocContainerOpenCB cb(isValidatedOnline); + std::unique_ptr doc = digidoc::Container::openPtr(containerPath.UTF8String, &cb); for (int i = 0; i < doc->signatures().size(); i++) { digidoc::Signature *signature = doc->signatures().at(i); digidoc::X509Cert cert = signature->signingCertificate(); @@ -937,7 +969,10 @@ - (NSString *)getMoppLibVersion { - (void)container:(NSString *)containerPath saveDataFile:(NSString *)fileName to:(NSString *)path success:(VoidBlock)success failure:(FailureBlock)failure { std::unique_ptr doc; try { - doc = digidoc::Container::openPtr(containerPath.UTF8String); + MoppLibDigidocValidateOnline *validateOnlineInstance = [MoppLibDigidocValidateOnline sharedInstance]; + BOOL isValidatedOnline = validateOnlineInstance.validateOnline; + MoppLibDigidocContainerOpenCB cb(isValidatedOnline); + doc = digidoc::Container::openPtr(containerPath.UTF8String, &cb); } catch(const digidoc::Exception &e) { parseException(e); } @@ -970,7 +1005,10 @@ -(BOOL)isFileInContainer:(NSString *)fileName dataFile:(NSString *)dataFileName - (BOOL)isContainerFileSaveable:(NSString *)containerPath saveDataFile:(NSString *)fileName { std::unique_ptr doc; try { - doc = digidoc::Container::openPtr(containerPath.UTF8String); + MoppLibDigidocValidateOnline *validateOnlineInstance = [MoppLibDigidocValidateOnline sharedInstance]; + BOOL isValidatedOnline = validateOnlineInstance.validateOnline; + MoppLibDigidocContainerOpenCB cb(isValidatedOnline); + doc = digidoc::Container::openPtr(containerPath.UTF8String, &cb); } catch(const digidoc::Exception &e) { parseException(e); } diff --git a/MoppLib/MoppLib/MoppLibDigidocValidateOnline.h b/MoppLib/MoppLib/MoppLibDigidocValidateOnline.h new file mode 100644 index 000000000..16ed7354e --- /dev/null +++ b/MoppLib/MoppLib/MoppLibDigidocValidateOnline.h @@ -0,0 +1,33 @@ +// +// MoppLibDigidocValidateOnline.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 + +@interface MoppLibDigidocValidateOnline : NSObject + +@property(nonatomic, assign) BOOL validateOnline; + ++ (MoppLibDigidocValidateOnline *)sharedInstance; + +@end + diff --git a/MoppLib/MoppLib/MoppLibDigidocValidateOnline.m b/MoppLib/MoppLib/MoppLibDigidocValidateOnline.m new file mode 100644 index 000000000..026cd646d --- /dev/null +++ b/MoppLib/MoppLib/MoppLibDigidocValidateOnline.m @@ -0,0 +1,39 @@ +// +// MoppLibDigidocValidateOnline.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 + +#import "MoppLibDigidocValidateOnline.h" + +@implementation MoppLibDigidocValidateOnline + ++ (MoppLibDigidocValidateOnline *)sharedInstance { + static MoppLibDigidocValidateOnline *sharedInstance = nil; + static dispatch_once_t pred; + dispatch_once(&pred, ^{ + sharedInstance = [[self alloc] init]; + }); + return sharedInstance; +} + +@end diff --git a/MoppLib/MoppLib/PublicInterface/MoppLib.h b/MoppLib/MoppLib/PublicInterface/MoppLib.h index c26909617..496e9eb48 100644 --- a/MoppLib/MoppLib/PublicInterface/MoppLib.h +++ b/MoppLib/MoppLib/PublicInterface/MoppLib.h @@ -44,3 +44,4 @@ FOUNDATION_EXPORT const unsigned char MoppLibVersionString[]; #import #import #import +#import From 5226237c009ff1956386fac766390e7ebb9061b7 Mon Sep 17 00:00:00 2001 From: Marten Rebane <54431068+martenrebane@users.noreply.github.com> Date: Tue, 5 Mar 2024 11:28:40 +0200 Subject: [PATCH 2/4] Code fixes --- MoppApp/MoppApp/MimeTypeExtractor.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/MoppApp/MoppApp/MimeTypeExtractor.swift b/MoppApp/MoppApp/MimeTypeExtractor.swift index a1bbc7876..3a9027886 100644 --- a/MoppApp/MoppApp/MimeTypeExtractor.swift +++ b/MoppApp/MoppApp/MimeTypeExtractor.swift @@ -53,8 +53,6 @@ class MimeTypeExtractor { public static func getMimeTypeFromContainer(filePath: URL) -> String { - let isCades = isCadesContainer(filePath: filePath) - var mimetype: String = "" if isZipFile(filePath: filePath) { From 14f6e92c301f954828ae05f19104180ccae7d256 Mon Sep 17 00:00:00 2001 From: Marten Rebane <54431068+martenrebane@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:42:07 +0200 Subject: [PATCH 3/4] Fix opening different types of files --- MoppApp/MoppApp/ContainerActions.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/MoppApp/MoppApp/ContainerActions.swift b/MoppApp/MoppApp/ContainerActions.swift index b47103158..45916756a 100644 --- a/MoppApp/MoppApp/ContainerActions.swift +++ b/MoppApp/MoppApp/ContainerActions.swift @@ -35,10 +35,8 @@ extension ContainerActions where Self: UIViewController { let topSigningViewController = navController.viewControllers.last! landingViewController.documentPicker.dismiss(animated: false, completion: nil) - - if landingViewController.fileImportIntent == .openOrCreate && landingViewController.containerType == .asic && urls.count == 1 { - self.importDataFiles(with: urls, navController: navController, topSigningViewController: topSigningViewController, landingViewController: landingViewController, cleanup: cleanup, isEmptyFileImported: isEmptyFileImported, isSendingToSivaAgreed: true) - } + + self.importDataFiles(with: urls, navController: navController, topSigningViewController: topSigningViewController, landingViewController: landingViewController, cleanup: cleanup, isEmptyFileImported: isEmptyFileImported, isSendingToSivaAgreed: true) } func importDataFiles(with urls: [URL], navController: UINavigationController, topSigningViewController: UIViewController, landingViewController: LandingViewController, cleanup: Bool, isEmptyFileImported: Bool, isSendingToSivaAgreed: Bool) { From a943d3c049c8ee8f5fafd15c95a3826f114434bd Mon Sep 17 00:00:00 2001 From: Marten Rebane <54431068+martenrebane@users.noreply.github.com> Date: Fri, 8 Mar 2024 15:48:01 +0200 Subject: [PATCH 4/4] Fix encrypting crash --- MoppApp/MoppApp/ContainerViewController.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MoppApp/MoppApp/ContainerViewController.swift b/MoppApp/MoppApp/ContainerViewController.swift index 7aa427eec..c8f28eede 100644 --- a/MoppApp/MoppApp/ContainerViewController.swift +++ b/MoppApp/MoppApp/ContainerViewController.swift @@ -244,8 +244,10 @@ class ContainerViewController : MoppViewController, ContainerActions, PreviewAct if isAsicsContainer() && !isAsicsFileWarningSet { handleAsicsContainerMessage() } - - checkIsCades(asicContainer: asicContainer) + + if isAsicContainer { + checkIsCades(asicContainer: asicContainer) + } if !isForPreview && isAsicContainer { if isDdocOrAsicsContainer(containerPath: containerPath) || isEmptyFileWarningSet || isCades() {