38 lines
1.0 KiB
Swift
38 lines
1.0 KiB
Swift
import Foundation
|
|
import LocalData
|
|
import Security
|
|
|
|
nonisolated
|
|
struct ExternalKeyMaterialProvider: KeyMaterialProviding {
|
|
private enum Constants {
|
|
static let service = "com.example.securestorage.externalkey"
|
|
static let keyLength = 32
|
|
}
|
|
|
|
func keyMaterial(for keyName: String) async throws -> Data {
|
|
if let existing = try await KeychainHelper.shared.get(
|
|
service: Constants.service,
|
|
key: keyName
|
|
) {
|
|
return existing
|
|
}
|
|
|
|
var bytes = [UInt8](repeating: 0, count: Constants.keyLength)
|
|
let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
|
|
guard status == errSecSuccess else {
|
|
throw StorageError.securityApplicationFailed
|
|
}
|
|
|
|
let material = Data(bytes)
|
|
try await KeychainHelper.shared.set(
|
|
material,
|
|
service: Constants.service,
|
|
key: keyName,
|
|
accessibility: .afterFirstUnlock,
|
|
accessControl: nil
|
|
)
|
|
|
|
return material
|
|
}
|
|
}
|