Verifies downloaded app’s version matches source

This commit is contained in:
Riley Testut
2023-05-11 17:47:03 -05:00
committed by Magesh K
parent d560e14423
commit 44e08b2d66
2 changed files with 21 additions and 0 deletions

View File

@@ -22,6 +22,7 @@ extension VerificationError
case iOSVersionNotSupported = 2 case iOSVersionNotSupported = 2
case mismatchedHash = 3 case mismatchedHash = 3
case mismatchedVersion = 4
} }
static func mismatchedBundleIdentifiers(sourceBundleID: String, app: ALTApplication) -> VerificationError { static func mismatchedBundleIdentifiers(sourceBundleID: String, app: ALTApplication) -> VerificationError {
@@ -35,6 +36,10 @@ extension VerificationError
static func mismatchedHash(_ hash: String, expectedHash: String, app: AppProtocol) -> VerificationError { static func mismatchedHash(_ hash: String, expectedHash: String, app: AppProtocol) -> VerificationError {
VerificationError(code: .mismatchedHash, app: app, hash: hash, expectedHash: expectedHash) VerificationError(code: .mismatchedHash, app: app, hash: hash, expectedHash: expectedHash)
} }
static func mismatchedVersion(_ version: String, expectedVersion: String, app: AppProtocol) -> VerificationError {
VerificationError(code: .mismatchedVersion, app: app, version: version, expectedVersion: expectedVersion)
}
} }
struct VerificationError: ALTLocalizedError struct VerificationError: ALTLocalizedError
@@ -52,6 +57,9 @@ struct VerificationError: ALTLocalizedError
@UserInfoValue var hash: String? @UserInfoValue var hash: String?
@UserInfoValue var expectedHash: String? @UserInfoValue var expectedHash: String?
@UserInfoValue var version: String?
@UserInfoValue var expectedVersion: String?
var errorDescription: String? { var errorDescription: String? {
//TODO: Make this automatic somehow with ALTLocalizedError //TODO: Make this automatic somehow with ALTLocalizedError
guard self.errorFailure == nil else { return nil } guard self.errorFailure == nil else { return nil }
@@ -117,6 +125,10 @@ struct VerificationError: ALTLocalizedError
case .mismatchedHash: case .mismatchedHash:
let appName = self.$app.name ?? NSLocalizedString("the downloaded app", comment: "") let appName = self.$app.name ?? NSLocalizedString("the downloaded app", comment: "")
return String(format: NSLocalizedString("The SHA-256 hash of %@ does not match the hash specified by the source.", comment: ""), appName) return String(format: NSLocalizedString("The SHA-256 hash of %@ does not match the hash specified by the source.", comment: ""), appName)
case .mismatchedVersion:
let appName = self.$app.name ?? NSLocalizedString("the app", comment: "")
return String(format: NSLocalizedString("The downloaded version of %@ does not match the version specified by the source.", comment: ""), appName)
} }
} }
} }

View File

@@ -142,7 +142,9 @@ final class VerifyAppOperation: ResultOperation<Void>
do do
{ {
guard let ipaURL = self.context.ipaURL else { throw OperationError.appNotFound(name: app.name) } guard let ipaURL = self.context.ipaURL else { throw OperationError.appNotFound(name: app.name) }
try await self.verifyHash(of: app, at: ipaURL, matches: appVersion) try await self.verifyHash(of: app, at: ipaURL, matches: appVersion)
try await self.verifyDownloadedVersion(of: app, matches: appVersion)
self.finish(.success(())) self.finish(.success(()))
} }
@@ -174,4 +176,11 @@ private extension VerifyAppOperation
guard hashString == expectedHash else { throw VerificationError.mismatchedHash(hashString, expectedHash: expectedHash, app: app) } guard hashString == expectedHash else { throw VerificationError.mismatchedHash(hashString, expectedHash: expectedHash, app: app) }
} }
func verifyDownloadedVersion(of app: ALTApplication, @AsyncManaged matches appVersion: AppVersion) async throws
{
let version = await $appVersion.version
guard version == app.version else { throw VerificationError.mismatchedVersion(app.version, expectedVersion: version, app: app) }
}
} }