UpdateManifestTests.swift
83 lines 3.0 KB
Raw
sha256:bd1eb24434d281fe65142038c1bf217493421f5a86880c22dff7e6037d2d4700 feat(companion): add production macOS distribution path Human minor ⚠ breaking 24 days ago
1 import CryptoKit
2 import Foundation
3 import XCTest
4 @testable import KnowtationSecurity
5
6 final class UpdateManifestTests: XCTestCase {
7 private func manifest(targetBuild: Int = 101, floor: Int = 100) -> SignedUpdateManifest {
8 SignedUpdateManifest(
9 schema: 1,
10 channel: "stable",
11 platform: "macos",
12 architecture: "arm64",
13 keyID: "release-key-1",
14 issuedAt: 1_000,
15 expiresAt: 2_000,
16 source: .init(minimumBuild: 100, maximumBuild: 100),
17 target: .init(
18 version: "0.1.1",
19 build: targetBuild,
20 packageURL: "https://releases.knowtation.store/stable/Knowtation.pkg",
21 packageSHA256: String(repeating: "a", count: 64),
22 packageBytes: 1024
23 ),
24 minimumAcceptedBuild: floor
25 )
26 }
27
28 private let context = UpdateEvaluationContext(
29 currentBuild: 100,
30 persistedFloor: 100,
31 now: 1_500
32 )
33
34 func testAcceptsValidUpgrade() throws {
35 XCTAssertEqual(
36 try UpdateManifestVerifier.evaluate(manifest(), expectedKeyID: "release-key-1", context: context).build,
37 101
38 )
39 }
40
41 func testRejectsRollbackAndReplay() {
42 XCTAssertThrowsError(try UpdateManifestVerifier.evaluate(
43 manifest(targetBuild: 99, floor: 101),
44 expectedKeyID: "release-key-1",
45 context: context
46 ))
47 }
48
49 func testRejectsExpiredManifest() {
50 let expiredContext = UpdateEvaluationContext(currentBuild: 100, persistedFloor: 100, now: 3_000)
51 XCTAssertThrowsError(try UpdateManifestVerifier.evaluate(
52 manifest(), expectedKeyID: "release-key-1", context: expiredContext
53 )) { XCTAssertEqual($0 as? UpdateRejection, .expired) }
54 }
55
56 func testRejectsWrongPlatformAndKey() {
57 let wrongPlatform = UpdateEvaluationContext(
58 currentBuild: 100, persistedFloor: 100, now: 1_500, platform: "linux"
59 )
60 XCTAssertThrowsError(try UpdateManifestVerifier.evaluate(
61 manifest(), expectedKeyID: "release-key-1", context: wrongPlatform
62 )) { XCTAssertEqual($0 as? UpdateRejection, .wrongPlatform) }
63 XCTAssertThrowsError(try UpdateManifestVerifier.evaluate(
64 manifest(), expectedKeyID: "release-key-2", context: context
65 )) { XCTAssertEqual($0 as? UpdateRejection, .wrongKey) }
66 }
67
68 func testEd25519SignatureRejectsTamper() throws {
69 let key = Curve25519.Signing.PrivateKey()
70 let data = Data("manifest".utf8)
71 let signature = try key.signature(for: data)
72 XCTAssertNoThrow(try UpdateManifestVerifier.verifySignature(
73 manifestData: data,
74 signature: signature,
75 publicKey: key.publicKey.rawRepresentation
76 ))
77 XCTAssertThrowsError(try UpdateManifestVerifier.verifySignature(
78 manifestData: Data("tampered".utf8),
79 signature: signature,
80 publicKey: key.publicKey.rawRepresentation
81 ))
82 }
83 }
File History 1 commit
sha256:bd1eb24434d281fe65142038c1bf217493421f5a86880c22dff7e6037d2d4700 feat(companion): add production macOS distribution path Human minor ⚠ 24 days ago