Summary: - Sources: Helpers, Protocols, Services - Tests: EncryptionHelperTests.swift, KeychainHelperTests.swift, LocalDataTests.swift, Mocks, StorageCatalogTests.swift - Added symbols: func updateKeychainHelper, actor KeychainHelper, protocol KeychainStoring, func set, func get, func delete (+4 more) - Removed symbols: actor KeychainHelper, func clearMasterKey Stats: - 9 files changed, 205 insertions(+), 103 deletions(-)
118 lines
3.4 KiB
Swift
118 lines
3.4 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import LocalData
|
|
|
|
@Suite(.serialized)
|
|
struct EncryptionHelperTests {
|
|
private let masterKeyService = "LocalData"
|
|
private let keyName = "LocalDataTests.encryption"
|
|
private let payload = Data("payload".utf8)
|
|
private let keychain = MockKeychainHelper()
|
|
private let encryption: EncryptionHelper
|
|
|
|
init() {
|
|
self.encryption = EncryptionHelper(keychain: keychain)
|
|
}
|
|
|
|
@Test func aesGCMWithPBKDF2RoundTrip() async throws {
|
|
let policy: SecurityPolicy.EncryptionPolicy = .aes256(
|
|
keyDerivation: .pbkdf2(iterations: 1_000)
|
|
)
|
|
|
|
let encrypted = try await encryption.encrypt(
|
|
payload,
|
|
keyName: keyName,
|
|
policy: policy
|
|
)
|
|
let decrypted = try await encryption.decrypt(
|
|
encrypted,
|
|
keyName: keyName,
|
|
policy: policy
|
|
)
|
|
|
|
#expect(decrypted == payload)
|
|
}
|
|
|
|
@Test func chaChaPolyWithHKDFRoundTrip() async throws {
|
|
let policy: SecurityPolicy.EncryptionPolicy = .chacha20Poly1305(
|
|
keyDerivation: .hkdf()
|
|
)
|
|
|
|
let encrypted = try await encryption.encrypt(
|
|
payload,
|
|
keyName: keyName,
|
|
policy: policy
|
|
)
|
|
let decrypted = try await encryption.decrypt(
|
|
encrypted,
|
|
keyName: keyName,
|
|
policy: policy
|
|
)
|
|
|
|
#expect(decrypted == payload)
|
|
}
|
|
|
|
@Test func customConfigurationRoundTrip() async throws {
|
|
let customService = "Test.CustomService"
|
|
let customAccount = "Test.CustomAccount"
|
|
let config = EncryptionConfiguration(
|
|
masterKeyService: customService,
|
|
masterKeyAccount: customAccount
|
|
)
|
|
|
|
await encryption.updateConfiguration(config)
|
|
|
|
let policy: SecurityPolicy.EncryptionPolicy = .chacha20Poly1305(
|
|
keyDerivation: .hkdf()
|
|
)
|
|
|
|
let encrypted = try await encryption.encrypt(
|
|
payload,
|
|
keyName: keyName,
|
|
policy: policy
|
|
)
|
|
let decrypted = try await encryption.decrypt(
|
|
encrypted,
|
|
keyName: keyName,
|
|
policy: policy
|
|
)
|
|
|
|
#expect(decrypted == payload)
|
|
|
|
// Cleanup mock keychain
|
|
try await keychain.deleteAll(service: customService)
|
|
}
|
|
|
|
@Test func externalProviderWithHKDFRoundTrip() async throws {
|
|
let source = KeyMaterialSource(id: "test.external")
|
|
let provider = StaticKeyMaterialProvider(material: Data(repeating: 7, count: 32))
|
|
await encryption.registerKeyMaterialProvider(provider, for: source)
|
|
|
|
let policy: SecurityPolicy.EncryptionPolicy = .external(
|
|
source: source,
|
|
keyDerivation: .hkdf()
|
|
)
|
|
|
|
let encrypted = try await encryption.encrypt(
|
|
payload,
|
|
keyName: keyName,
|
|
policy: policy
|
|
)
|
|
let decrypted = try await encryption.decrypt(
|
|
encrypted,
|
|
keyName: keyName,
|
|
policy: policy
|
|
)
|
|
|
|
#expect(decrypted == payload)
|
|
}
|
|
}
|
|
|
|
private struct StaticKeyMaterialProvider: KeyMaterialProviding {
|
|
let material: Data
|
|
|
|
func keyMaterial(for keyName: String) async throws -> Data {
|
|
material
|
|
}
|
|
}
|