mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-04-10 17:47:19 +00:00
Load auth settings.
This commit is contained in:
parent
53c8629870
commit
e7e9f2b7f9
@ -183,7 +183,7 @@ extension SecureEnclave.Store {
|
|||||||
|
|
||||||
/// Loads all secrets from the store.
|
/// Loads all secrets from the store.
|
||||||
private func loadSecrets() {
|
private func loadSecrets() {
|
||||||
let attributes = [
|
let publicAttributes = [
|
||||||
kSecClass: kSecClassKey,
|
kSecClass: kSecClassKey,
|
||||||
kSecAttrKeyType: SecureEnclave.Constants.keyType,
|
kSecAttrKeyType: SecureEnclave.Constants.keyType,
|
||||||
kSecAttrApplicationTag: SecureEnclave.Constants.keyTag,
|
kSecAttrApplicationTag: SecureEnclave.Constants.keyTag,
|
||||||
@ -192,16 +192,46 @@ extension SecureEnclave.Store {
|
|||||||
kSecMatchLimit: kSecMatchLimitAll,
|
kSecMatchLimit: kSecMatchLimitAll,
|
||||||
kSecReturnAttributes: true
|
kSecReturnAttributes: true
|
||||||
] as CFDictionary
|
] as CFDictionary
|
||||||
var untyped: CFTypeRef?
|
var publicUntyped: CFTypeRef?
|
||||||
SecItemCopyMatching(attributes, &untyped)
|
SecItemCopyMatching(publicAttributes, &publicUntyped)
|
||||||
guard let typed = untyped as? [[CFString: Any]] else { return }
|
guard let publicTyped = publicUntyped as? [[CFString: Any]] else { return }
|
||||||
let wrapped: [SecureEnclave.Secret] = typed.map {
|
let privateAttributes = [
|
||||||
|
kSecClass: kSecClassKey,
|
||||||
|
kSecAttrKeyType: SecureEnclave.Constants.keyType,
|
||||||
|
kSecAttrApplicationTag: SecureEnclave.Constants.keyTag,
|
||||||
|
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
|
||||||
|
kSecReturnRef: true,
|
||||||
|
kSecMatchLimit: kSecMatchLimitAll,
|
||||||
|
kSecReturnAttributes: true
|
||||||
|
] as CFDictionary
|
||||||
|
var privateUntyped: CFTypeRef?
|
||||||
|
SecItemCopyMatching(privateAttributes, &privateUntyped)
|
||||||
|
guard let privateTyped = privateUntyped as? [[CFString: Any]] else { return }
|
||||||
|
let privateMapped = privateTyped.reduce(into: [:] as [Data: [CFString: Any]]) { partialResult, next in
|
||||||
|
let id = next[kSecAttrApplicationLabel] as! Data
|
||||||
|
partialResult[id] = next
|
||||||
|
}
|
||||||
|
let authNotRequiredAccessControl: SecAccessControl =
|
||||||
|
SecAccessControlCreateWithFlags(kCFAllocatorDefault,
|
||||||
|
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
|
||||||
|
[.privateKeyUsage],
|
||||||
|
nil)!
|
||||||
|
|
||||||
|
let wrapped: [SecureEnclave.Secret] = publicTyped.map {
|
||||||
let name = $0[kSecAttrLabel] as? String ?? "Unnamed"
|
let name = $0[kSecAttrLabel] as? String ?? "Unnamed"
|
||||||
let id = $0[kSecAttrApplicationLabel] as! Data
|
let id = $0[kSecAttrApplicationLabel] as! Data
|
||||||
let publicKeyRef = $0[kSecValueRef] as! SecKey
|
let publicKeyRef = $0[kSecValueRef] as! SecKey
|
||||||
let publicKeyAttributes = SecKeyCopyAttributes(publicKeyRef) as! [CFString: Any]
|
let publicKeyAttributes = SecKeyCopyAttributes(publicKeyRef) as! [CFString: Any]
|
||||||
let publicKey = publicKeyAttributes[kSecValueData] as! Data
|
let publicKey = publicKeyAttributes[kSecValueData] as! Data
|
||||||
return SecureEnclave.Secret(id: id, name: name, requiresAuthentication: false, publicKey: publicKey)
|
let privateKey = privateMapped[id]
|
||||||
|
let requiresAuth: Bool
|
||||||
|
if let authRequirements = privateKey?[kSecAttrAccessControl] {
|
||||||
|
// Unfortunately we can't inspect the access control object directly, but it does behave predicatable with equality.
|
||||||
|
requiresAuth = authRequirements as! SecAccessControl != authNotRequiredAccessControl
|
||||||
|
} else {
|
||||||
|
requiresAuth = false
|
||||||
|
}
|
||||||
|
return SecureEnclave.Secret(id: id, name: name, requiresAuthentication: requiresAuth, publicKey: publicKey)
|
||||||
}
|
}
|
||||||
secrets.append(contentsOf: wrapped)
|
secrets.append(contentsOf: wrapped)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user