Skip to content

Commit

Permalink
Merge pull request #334 from tangem/IOS-4876_refactor_backup_flow
Browse files Browse the repository at this point in the history
IOS-4876 Split certificate loading
  • Loading branch information
tureck1y authored Dec 29, 2023
2 parents 342eacb + ef8710d commit 32ba658
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 311 deletions.
7 changes: 4 additions & 3 deletions TangemSdk/TangemSdk.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
5D0243BE26CACACD00B76F37 /* IndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0243BD26CACACD00B76F37 /* IndicatorView.swift */; };
5D04F9E226EF731B00D15F75 /* Publisher+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D04F9E126EF731B00D15F75 /* Publisher+.swift */; };
5D0631DB2477DAAA0056BF21 /* OpenSessionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0631DA2477DAAA0056BF21 /* OpenSessionCommand.swift */; };
5D06F6AD27565441006A15B9 /* StartPrimaryCardLinkingTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D06F6AC27565441006A15B9 /* StartPrimaryCardLinkingTask.swift */; };
5D0A6C5D2428CF3C0094FA83 /* Error+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A6C5C2428CF3C0094FA83 /* Error+.swift */; };
5D0BAAEC25CD87EA00E6A2B6 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0BAAEB25CD87EA00E6A2B6 /* Log.swift */; };
5D0E56032757C11F00D46F54 /* CardDataResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0E56022757C11F00D46F54 /* CardDataResponse.swift */; };
Expand Down Expand Up @@ -268,6 +267,7 @@
DC1244E429BB806E0037BC05 /* WIFTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC1244E329BB806E0037BC05 /* WIFTests.swift */; };
DC1244E629BB8E580037BC05 /* NetworkType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC1244E529BB8E580037BC05 /* NetworkType.swift */; };
DC1244E829BB9E0C0037BC05 /* ExtendedKeySerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC1244E729BB9E0C0037BC05 /* ExtendedKeySerializer.swift */; };
DC1682202B3C355600194DDE /* BackupCertificateProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC16821F2B3C355600194DDE /* BackupCertificateProvider.swift */; };
DC22228729D431AB001129F8 /* SetUserCodeRecoveryAllowed.json in Resources */ = {isa = PBXBuildFile; fileRef = DC22228629D431AB001129F8 /* SetUserCodeRecoveryAllowed.json */; };
DC234CC629F1A3F100082063 /* ImportWalletMnemonic.json in Resources */ = {isa = PBXBuildFile; fileRef = DC234CC529F1A3F100082063 /* ImportWalletMnemonic.json */; };
DC30D70A2AF024D000744FA4 /* PreflightReadFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC30D7092AF024D000744FA4 /* PreflightReadFilter.swift */; };
Expand Down Expand Up @@ -392,7 +392,6 @@
5D04F9E126EF731B00D15F75 /* Publisher+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Publisher+.swift"; sourceTree = "<group>"; };
5D0631DA2477DAAA0056BF21 /* OpenSessionCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSessionCommand.swift; sourceTree = "<group>"; };
5D06DF6823D8A1EE0041DD2B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
5D06F6AC27565441006A15B9 /* StartPrimaryCardLinkingTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartPrimaryCardLinkingTask.swift; sourceTree = "<group>"; };
5D0A6C5C2428CF3C0094FA83 /* Error+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+.swift"; sourceTree = "<group>"; };
5D0BAAEB25CD87EA00E6A2B6 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
5D0E56022757C11F00D46F54 /* CardDataResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardDataResponse.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -657,6 +656,7 @@
DC1244E329BB806E0037BC05 /* WIFTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WIFTests.swift; sourceTree = "<group>"; };
DC1244E529BB8E580037BC05 /* NetworkType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkType.swift; sourceTree = "<group>"; };
DC1244E729BB9E0C0037BC05 /* ExtendedKeySerializer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedKeySerializer.swift; sourceTree = "<group>"; };
DC16821F2B3C355600194DDE /* BackupCertificateProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupCertificateProvider.swift; sourceTree = "<group>"; };
DC22228629D431AB001129F8 /* SetUserCodeRecoveryAllowed.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = SetUserCodeRecoveryAllowed.json; sourceTree = "<group>"; };
DC234CC529F1A3F100082063 /* ImportWalletMnemonic.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ImportWalletMnemonic.json; sourceTree = "<group>"; };
DC30D7092AF024D000744FA4 /* PreflightReadFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreflightReadFilter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1034,8 +1034,8 @@
5DED473226D6A00D003CB1E7 /* BackupService.swift */,
5D8D257626EA66BD00146039 /* ResetBackupCommand.swift */,
5D492E9926EA8EE600F489F5 /* StartBackupCardLinkingTask.swift */,
5D06F6AC27565441006A15B9 /* StartPrimaryCardLinkingTask.swift */,
DCD2D5BB2A1CA1EB00AB00B6 /* FinalizeReadBackupDataCommand.swift */,
DC16821F2B3C355600194DDE /* BackupCertificateProvider.swift */,
);
path = Backup;
sourceTree = "<group>";
Expand Down Expand Up @@ -1979,6 +1979,7 @@
5D974B7E237D672F00DCDF21 /* Date+.swift in Sources */,
5D6831D223DB2EA30095BB1D /* CreateWalletCommand.swift in Sources */,
5D60CA63272C472F00A1DF0B /* ResetCodesController.swift in Sources */,
DC1682202B3C355600194DDE /* BackupCertificateProvider.swift in Sources */,
5D908C6126A75DB700270FA3 /* ReadView.swift in Sources */,
DC3D98022A77F5DB001EEE7A /* IkarusMasterKeyFactory.swift in Sources */,
5D0243BE26CACACD00B76F37 /* IndicatorView.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// BackupCertificateProvider.swift
// TangemSdk
//
// Created by Alexander Osokin on 27.12.2023.
// Copyright © 2023 Tangem AG. All rights reserved.
//

import Foundation
import Combine

@available(iOS 13.0, *)
class BackupCertificateProvider {
private let onlineCardVerifier = OnlineCardVerifier()
private var cancellable: AnyCancellable? = nil
private let developmentMode: Bool

private let sdkIssuerPrivateKey = Data(hexString: "11121314151617184771ED81F2BACF57479E4735EB1405083927372D40DA9E92")

init(developmentMode: Bool) {
self.developmentMode = developmentMode
}

func getCertificate(for cardId: String, cardPublicKey: Data, _ completion: @escaping CompletionResult<Data>) {
loadSignature(for: cardId, cardPublicKey: cardPublicKey) { loadCompletion in
switch loadCompletion {
case .success(let signature):
do {
let certificate = try BackupCertificateProvider.generateCertificate(cardPublicKey: cardPublicKey, issuerSignature: signature)
completion(.success(certificate))
} catch {
completion(.failure(error.toTangemSdkError()))
}
case .failure(let error):
completion(.failure(error))
}
}
}

private func loadSignature(for cardId: String, cardPublicKey: Data, _ completion: @escaping CompletionResult<Data>) {
if developmentMode {
do {
let sdkIssuerSignature = try cardPublicKey.sign(privateKey: sdkIssuerPrivateKey)
completion(.success(sdkIssuerSignature))
} catch {
completion(.failure(error.toTangemSdkError()))
}
return
}

cancellable = onlineCardVerifier
.getCardData(cardId: cardId, cardPublicKey: cardPublicKey)
.sink(receiveCompletion: { receivedCompletion in
if case .failure = receivedCompletion {
completion(.failure(.issuerSignatureLoadingFailed))
}
}, receiveValue: { response in
guard let signature = response.issuerSignature else {
completion(.failure(.issuerSignatureLoadingFailed))
return
}

completion(.success(signature))
})
}

private static func generateCertificate(cardPublicKey: Data, issuerSignature: Data) throws -> Data {
return try TlvBuilder()
.append(.cardPublicKey, value: cardPublicKey)
.append(.issuerDataSignature, value: issuerSignature)
.serialize()
}
}
Loading

0 comments on commit 32ba658

Please sign in to comment.