Add StorageKeys, ExternalKeyMaterialKey, Value
This commit is contained in:
parent
3efb77bc32
commit
e7115693a1
@ -13,7 +13,7 @@ struct SecureStorgageSampleApp: App {
|
|||||||
init() {
|
init() {
|
||||||
_ = WatchConnectivityService.shared
|
_ = WatchConnectivityService.shared
|
||||||
Task {
|
Task {
|
||||||
await EncryptionHelper.shared.registerKeyMaterialProvider(
|
await StorageRouter.shared.registerKeyMaterialProvider(
|
||||||
ExternalKeyMaterialProvider(),
|
ExternalKeyMaterialProvider(),
|
||||||
for: SampleKeyMaterialSources.external
|
for: SampleKeyMaterialSources.external
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,37 +1,26 @@
|
|||||||
|
import CryptoKit
|
||||||
import Foundation
|
import Foundation
|
||||||
import LocalData
|
import LocalData
|
||||||
import Security
|
|
||||||
|
|
||||||
nonisolated
|
nonisolated
|
||||||
struct ExternalKeyMaterialProvider: KeyMaterialProviding {
|
struct ExternalKeyMaterialProvider: KeyMaterialProviding {
|
||||||
private enum Constants {
|
private enum Constants {
|
||||||
static let service = "com.example.securestorage.externalkey"
|
|
||||||
static let keyLength = 32
|
static let keyLength = 32
|
||||||
}
|
}
|
||||||
|
|
||||||
func keyMaterial(for keyName: String) async throws -> Data {
|
func keyMaterial(for keyName: String) async throws -> Data {
|
||||||
if let existing = try await KeychainHelper.shared.get(
|
let key = StorageKeys.ExternalKeyMaterialKey(keyName: keyName)
|
||||||
service: Constants.service,
|
if let existing = try await StorageRouter.shared.get(key) as Data? {
|
||||||
key: keyName
|
|
||||||
) {
|
|
||||||
return existing
|
return existing
|
||||||
}
|
}
|
||||||
|
|
||||||
var bytes = [UInt8](repeating: 0, count: Constants.keyLength)
|
let symmetricKey = SymmetricKey(size: .bits256)
|
||||||
let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
|
let material = symmetricKey.withUnsafeBytes { Data($0) }
|
||||||
guard status == errSecSuccess else {
|
guard material.count == Constants.keyLength else {
|
||||||
throw StorageError.securityApplicationFailed
|
throw StorageError.securityApplicationFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
let material = Data(bytes)
|
try await StorageRouter.shared.set(material, for: key)
|
||||||
try await KeychainHelper.shared.set(
|
|
||||||
material,
|
|
||||||
service: Constants.service,
|
|
||||||
key: keyName,
|
|
||||||
accessibility: .afterFirstUnlock,
|
|
||||||
accessControl: nil
|
|
||||||
)
|
|
||||||
|
|
||||||
return material
|
return material
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
import Foundation
|
||||||
|
import LocalData
|
||||||
|
|
||||||
|
extension StorageKeys {
|
||||||
|
/// Stores external key material used for encryption policies.
|
||||||
|
struct ExternalKeyMaterialKey: StorageKey {
|
||||||
|
typealias Value = Data
|
||||||
|
|
||||||
|
let name: String
|
||||||
|
let domain: StorageDomain = .keychain(service: "com.example.securestorage.externalkey")
|
||||||
|
let security: SecurityPolicy = .keychain(
|
||||||
|
accessibility: .afterFirstUnlock,
|
||||||
|
accessControl: nil
|
||||||
|
)
|
||||||
|
let serializer: Serializer<Data> = .data
|
||||||
|
let owner = "SampleApp"
|
||||||
|
let availability: PlatformAvailability = .phoneOnly
|
||||||
|
let syncPolicy: SyncPolicy = .never
|
||||||
|
|
||||||
|
init(keyName: String) {
|
||||||
|
self.name = keyName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user