Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions Mactrix.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
348E99882F40ABC3009F57A9 /* AsyncAlgorithms in Frameworks */ = {isa = PBXBuildFile; productRef = 348E99872F40ABC3009F57A9 /* AsyncAlgorithms */; };
34913F6E2EC0F532003034CB /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 34913F6D2EC0F532003034CB /* MatrixRustSDK */; };
34913F702EC0F59F003034CB /* Models in Frameworks */ = {isa = PBXBuildFile; productRef = 34913F6F2EC0F59F003034CB /* Models */; };
34F7225F2EB531F40007B2A4 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 34F7225E2EB531F40007B2A4 /* KeychainAccess */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -50,7 +49,6 @@
34913F6E2EC0F532003034CB /* MatrixRustSDK in Frameworks */,
345E77E82ED9F309002E5B9A /* Utils in Frameworks */,
34913F702EC0F59F003034CB /* Models in Frameworks */,
34F7225F2EB531F40007B2A4 /* KeychainAccess in Frameworks */,
348E99882F40ABC3009F57A9 /* AsyncAlgorithms in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -103,7 +101,6 @@
);
name = Mactrix;
packageProductDependencies = (
34F7225E2EB531F40007B2A4 /* KeychainAccess */,
3409F4EB2EBFD8D4009537B4 /* UI */,
34913F6D2EC0F532003034CB /* MatrixRustSDK */,
34913F6F2EC0F59F003034CB /* Models */,
Expand Down Expand Up @@ -140,7 +137,6 @@
minimizedProjectReferenceProxies = 1;
packageReferences = (
342C624C2EB4DDE600E2426A /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */,
34F7225D2EB531F40007B2A4 /* XCRemoteSwiftPackageReference "KeychainAccess" */,
3409F4E82EBFD8D4009537B4 /* XCLocalSwiftPackageReference "MactrixLibrary" */,
348E99862F40ABC3009F57A9 /* XCRemoteSwiftPackageReference "swift-async-algorithms" */,
);
Expand Down Expand Up @@ -450,14 +446,6 @@
minimumVersion = 1.1.2;
};
};
34F7225D2EB531F40007B2A4 /* XCRemoteSwiftPackageReference "KeychainAccess" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess";
requirement = {
branch = master;
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
Expand All @@ -483,11 +471,6 @@
isa = XCSwiftPackageProductDependency;
productName = Models;
};
34F7225E2EB531F40007B2A4 /* KeychainAccess */ = {
isa = XCSwiftPackageProductDependency;
package = 34F7225D2EB531F40007B2A4 /* XCRemoteSwiftPackageReference "KeychainAccess" */;
productName = KeychainAccess;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 3438583A2EB394590010922A /* Project object */;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 68 additions & 0 deletions Mactrix/Models/AppKeychain.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import Foundation
import Security

enum KeychainError: Error {
case unexpectedStatus(OSStatus)
}

struct AppKeychain {
private let service: String

init(service: String = Bundle.main.bundleIdentifier!) {
self.service = service
}

private var baseQuery: [CFString: Any] {
[
kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
/// change to true for Data Protection keychain mode
kSecUseDataProtectionKeychain: false,
]
}

/// Saves data for the given key, creating or updating the keychain item.
func save(_ data: Data, forKey key: String) throws {
var query = baseQuery
query[kSecAttrAccount] = key

let updateStatus = SecItemUpdate(query as CFDictionary, [kSecValueData: data] as CFDictionary)
if updateStatus == errSecItemNotFound {
query[kSecValueData] = data
query[kSecAttrAccessible] = kSecAttrAccessibleWhenUnlocked
let addStatus = SecItemAdd(query as CFDictionary, nil)
guard addStatus == errSecSuccess else {
throw KeychainError.unexpectedStatus(addStatus)
}
} else if updateStatus != errSecSuccess {
/// with kSecUseDataProtectionKeychain set to true, this will throw with error -34018, which according to
/// https://github.com/apple-oss-distributions/Security/blob/09becc8fb155462f0853f99cd09c26b10a38e2f4/sec/Security/SecBasePriv.h#L113
/// is the error "Internal error when a required entitlement isn't present"
throw KeychainError.unexpectedStatus(updateStatus)
}
}

/// Returns the data stored for the given key, or `nil` if no item exists.
func load(forKey key: String) throws -> Data? {
var query = baseQuery
query[kSecAttrAccount] = key
query[kSecReturnData] = true
query[kSecMatchLimit] = kSecMatchLimitOne

var result: AnyObject?
let status = unsafe SecItemCopyMatching(query as CFDictionary, &result)
if status == errSecItemNotFound { return nil }
guard status == errSecSuccess else {
throw KeychainError.unexpectedStatus(status)
}
return result as? Data
}

/// Removes all keychain items stored under this service.
func removeAll() throws {
let status = SecItemDelete(baseQuery as CFDictionary)
guard status == errSecSuccess || status == errSecItemNotFound else {
throw KeychainError.unexpectedStatus(status)
}
}
}
6 changes: 5 additions & 1 deletion Mactrix/Models/HomeserverLogin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ struct HomeserverLogin {
let matrixClient = await MatrixClient(storeID: storeID, client: unauthenticatedClient)

let userSession = try matrixClient.userSession()
try userSession.saveUserToKeychain()
do {
try userSession.saveUserToKeychain()
} catch {
print(error.localizedDescription)
}

return matrixClient
}
Expand Down
19 changes: 6 additions & 13 deletions Mactrix/Models/MatrixClient.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import AsyncAlgorithms
import Foundation
import KeychainAccess
import MatrixRustSDK
import OSLog
import SwiftUI
Expand Down Expand Up @@ -41,20 +40,15 @@ struct UserSession: Codable {

func saveUserToKeychain() throws {
let keychainData = try JSONEncoder().encode(self)
let keychain = Keychain(service: applicationID)
try keychain.set(keychainData, key: Self.keychainKey)
try AppKeychain().save(keychainData, forKey: Self.keychainKey)
}

static func loadUserFromKeychain() throws -> Self? {
Logger.matrixClient.debug("Load user from keychain")
/* #if DEBUG
if true {
return try JSONDecoder().decode(Self.self, from: DevSecrets.matrixSession.data(using: .utf8)!)
}
#endif */
let keychain = Keychain(service: applicationID)
guard let keychainData = try keychain.getData(keychainKey) else { return nil }
return try JSONDecoder().decode(Self.self, from: keychainData)
if let keychainData = try AppKeychain().load(forKey: Self.keychainKey) {
return try JSONDecoder().decode(Self.self, from: keychainData)
}
return nil
}
}

Expand Down Expand Up @@ -148,8 +142,7 @@ class MatrixClient {
try? await client.logout()
try? FileManager.default.removeItem(at: .sessionData(for: storeID))
try? FileManager.default.removeItem(at: .sessionCaches(for: storeID))
let keychain = Keychain(service: applicationID)
try keychain.removeAll()
try AppKeychain().removeAll()
Logger.matrixClient.debug("matrix client sign out complete")
}

Expand Down
1 change: 0 additions & 1 deletion Mactrix/Models/MatrixClientSessionDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import Foundation
import KeychainAccess
import MatrixRustSDK
import OSLog
import SwiftUI
Expand Down