Sesame-iOS/Sesame/KeyManagement.swift
2022-04-09 17:43:33 +02:00

97 lines
2.7 KiB
Swift

import Foundation
import CryptoKit
import SwiftUI
final class KeyManagement {
static let tag = "com.ch.sesame.key".data(using: .utf8)!
private static let label = "sesame"
private static let keyType = kSecAttrKeyTypeEC
private static let keyClass = kSecAttrKeyClassSymmetric
private static let query: [String: Any] = [
kSecClass as String: kSecClassInternetPassword,
kSecAttrAccount as String: "account",
kSecAttrServer as String: "christophhagen.de",
]//kSecAttrLabel as String: "sesame"]
private static func loadKeys() -> Data? {
var query = query
query[kSecReturnData as String] = kCFBooleanTrue
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
guard status == errSecSuccess else {
print("Failed to get key: \(status)")
return nil
}
let key = item as! CFData
print("Key loaded from keychain")
return key as Data
}
private static func deleteKeys() {
let status = SecItemDelete(query as CFDictionary)
guard status == errSecSuccess || status == errSecItemNotFound else {
print("Failed to remove key: \(status)")
return
}
print("Key removed from keychain")
}
private static func saveKeys(_ data: Data) {
var query = query
query[kSecValueData as String] = data
let status = SecItemAdd(query as CFDictionary, nil)
guard status == errSecSuccess else {
print("Failed to store key: \(status)")
return
}
print("Key saved to keychain")
}
private static var keyData: Data? = loadKeys() {
didSet {
guard let data = keyData else {
deleteKeys()
return
}
saveKeys(data)
}
}
static var hasKey: Bool {
key != nil
}
private(set) static var key: (device: SymmetricKey, remote: SymmetricKey)? {
get {
guard let data = keyData else {
return nil
}
let device = SymmetricKey(data: data.prefix(32))
let remote = SymmetricKey(data: data.advanced(by: 32))
return (device, remote)
}
set {
guard let key = newValue else {
keyData = nil
return
}
keyData = key.device.data + key.remote.data
}
}
static func generateNewKeys() {
let device = SymmetricKey(size: .bits256)
let remote = SymmetricKey(size: .bits256)
key = (device, remote)
print("New keys:")
print("Device: \(device.data.hexEncoded)")
print("Remote: \(remote.data.hexEncoded)")
}
}