This commit is contained in:
fmodf 2024-08-31 14:06:14 +02:00
parent 217dd152d3
commit deac1bf56e
2 changed files with 187 additions and 123 deletions

View file

@ -11,6 +11,12 @@ final class ClientMartinOMEMO {
init(_ credentials: Credentials) {
self.credentials = credentials
_ = regenerateKeys(wipe: false)
print("ClientMartinOMEMO init")
}
deinit {
print("ClientMartinOMEMO deinit")
}
var signal: (SignalStorage, SignalContext) {
@ -20,25 +26,25 @@ final class ClientMartinOMEMO {
signalStorage.setup(withContext: signalContext)
return (signalStorage, signalContext)
}
// func regenerateKeys(wipe: Bool = false) -> Bool {
// if wipe {
// wipeSignedPreKeys()
// }
// }
// if wipe {
// DBOMEMOStore.instance.wipe(forAccount: context!.sessionObject.userBareJid!)
// }
//
// let hasKeyPair = identityKeyStore.keyPair() != nil
// if wipe || identityKeyStore.localRegistrationId() == 0 || !hasKeyPair {
private func regenerateKeys(wipe: Bool = false) -> Bool {
if wipe {
OMEMOSession.wipe(account: credentials.bareJid)
OMEMOPreKey.wipe(account: credentials.bareJid)
OMEMOSignedPreKey.wipe(account: credentials.bareJid)
OMEMOIdentity.wipe(account: credentials.bareJid)
}
let hasKeyPair = keyPair() != nil
if wipe || localRegistrationId() == 0 || !hasKeyPair {
// let regId: UInt32 = signalContext.generateRegistrationId()
// AccountSettings.omemoRegistrationId(for: context!.sessionObject.userBareJid!, value: regId)
//
// let keyPair = SignalIdentityKeyPair.generateKeyPair(context: signalContext)
// if !identityKeyStore.save(identity: SignalAddress(name: context!.sessionObject.userBareJid!.stringValue, deviceId: Int32(identityKeyStore.localRegistrationId())), key: keyPair) {}
// }
// return true
// }
}
return true
}
}
// MARK: - Session
@ -123,6 +129,107 @@ extension ClientMartinOMEMO: SignalSessionStoreProtocol {
}
}
// MARK: - Identity
extension ClientMartinOMEMO: SignalIdentityKeyStoreProtocol {
func keyPair() -> (any MartinOMEMO.SignalIdentityKeyPairProtocol)? {
// guard let deviceId = localRegistrationId(forAccount: account) else {
// return nil
// }
//
// guard
// let data = try! Database.main.reader({ database in
// try database.select(query: .omemoKeyPairForAccount, params: ["account": account, "name": account.stringValue, "deviceId": deviceId]).mapFirst { $0.data(for: "key") }
// })
// else {
// return nil
// }
//
// return SignalIdentityKeyPair(fromKeyPairData: data)
nil
}
func localRegistrationId() -> UInt32 {
//
//
//
//
//
//
0
}
func save(identity: MartinOMEMO.SignalAddress, key: (any MartinOMEMO.SignalIdentityKeyProtocol)?) -> Bool {
print(identity, key)
return false
}
func save(identity: MartinOMEMO.SignalAddress, publicKeyData: Data?) -> Bool {
print(identity, publicKeyData)
return false
}
func isTrusted(identity _: MartinOMEMO.SignalAddress, key _: (any MartinOMEMO.SignalIdentityKeyProtocol)?) -> Bool {
true
}
func isTrusted(identity _: MartinOMEMO.SignalAddress, publicKeyData _: Data?) -> Bool {
true
}
func setStatus(_ status: MartinOMEMO.IdentityStatus, forIdentity: MartinOMEMO.SignalAddress) -> Bool {
print(status, forIdentity)
return false
}
func setStatus(active: Bool, forIdentity: MartinOMEMO.SignalAddress) -> Bool {
print(active, forIdentity)
return false
}
func identities(forName name: String) -> [MartinOMEMO.Identity] {
do {
return try Database.shared.dbQueue.read { db in
try Row.fetchAll(
db,
sql: "SELECT * FROM omemo_identities WHERE account = :account AND name = :name",
arguments: ["account": credentials.bareJid, "name": name]
)
}.compactMap { row in
guard
let fingerprint = row["fingerprint"] as? String,
let statusInt = row["status"] as? Int,
let status = MartinOMEMO.IdentityStatus(rawValue: statusInt),
let deviceId = row["device_id"] as? Int32,
let own = row["own"] as? Int,
let key = row["key"] as? Data
else {
return nil
}
return MartinOMEMO.Identity(address: MartinOMEMO.SignalAddress(name: name, deviceId: deviceId), status: status, fingerprint: fingerprint, key: key, own: own > 0)
}
} catch {
logIt(.error, "Error fetching chats: \(error.localizedDescription)")
return []
}
}
func identityFingerprint(forAddress address: MartinOMEMO.SignalAddress) -> String? {
do {
let data = try Database.shared.dbQueue.read { db in
try Row.fetchOne(
db,
sql: "SELECT fingerprint FROM omemo_identities WHERE account = :account AND name = :name AND device_id = :deviceId",
arguments: ["account": credentials.bareJid, "name": address.name, "deviceId": address.deviceId]
)
}
return data?["fingerprint"]
} catch {
logIt(.error, "Error fetching chats: \(error.localizedDescription)")
return nil
}
}
}
// MARK: - PreKey
extension ClientMartinOMEMO: SignalPreKeyStoreProtocol {
func currentPreKeyId() -> UInt32 {
@ -357,107 +464,6 @@ extension ClientMartinOMEMO: SignalSignedPreKeyStoreProtocol {
}
}
// MARK: - Identity
extension ClientMartinOMEMO: SignalIdentityKeyStoreProtocol {
func keyPair() -> (any MartinOMEMO.SignalIdentityKeyPairProtocol)? {
// guard let deviceId = localRegistrationId(forAccount: account) else {
// return nil
// }
//
// guard
// let data = try! Database.main.reader({ database in
// try database.select(query: .omemoKeyPairForAccount, params: ["account": account, "name": account.stringValue, "deviceId": deviceId]).mapFirst { $0.data(for: "key") }
// })
// else {
// return nil
// }
//
// return SignalIdentityKeyPair(fromKeyPairData: data)
nil
}
func localRegistrationId() -> UInt32 {
//
//
//
//
//
//
0
}
func save(identity: MartinOMEMO.SignalAddress, key: (any MartinOMEMO.SignalIdentityKeyProtocol)?) -> Bool {
print(identity, key)
return false
}
func save(identity: MartinOMEMO.SignalAddress, publicKeyData: Data?) -> Bool {
print(identity, publicKeyData)
return false
}
func isTrusted(identity _: MartinOMEMO.SignalAddress, key _: (any MartinOMEMO.SignalIdentityKeyProtocol)?) -> Bool {
true
}
func isTrusted(identity _: MartinOMEMO.SignalAddress, publicKeyData _: Data?) -> Bool {
true
}
func setStatus(_ status: MartinOMEMO.IdentityStatus, forIdentity: MartinOMEMO.SignalAddress) -> Bool {
print(status, forIdentity)
return false
}
func setStatus(active: Bool, forIdentity: MartinOMEMO.SignalAddress) -> Bool {
print(active, forIdentity)
return false
}
func identities(forName name: String) -> [MartinOMEMO.Identity] {
do {
return try Database.shared.dbQueue.read { db in
try Row.fetchAll(
db,
sql: "SELECT * FROM omemo_identities WHERE account = :account AND name = :name",
arguments: ["account": credentials.bareJid, "name": name]
)
}.compactMap { row in
guard
let fingerprint = row["fingerprint"] as? String,
let statusInt = row["status"] as? Int,
let status = MartinOMEMO.IdentityStatus(rawValue: statusInt),
let deviceId = row["device_id"] as? Int32,
let own = row["own"] as? Int,
let key = row["key"] as? Data
else {
return nil
}
return MartinOMEMO.Identity(address: MartinOMEMO.SignalAddress(name: name, deviceId: deviceId), status: status, fingerprint: fingerprint, key: key, own: own > 0)
}
} catch {
logIt(.error, "Error fetching chats: \(error.localizedDescription)")
return []
}
}
func identityFingerprint(forAddress address: MartinOMEMO.SignalAddress) -> String? {
do {
let data = try Database.shared.dbQueue.read { db in
try Row.fetchOne(
db,
sql: "SELECT fingerprint FROM omemo_identities WHERE account = :account AND name = :name AND device_id = :deviceId",
arguments: ["account": credentials.bareJid, "name": address.name, "deviceId": address.deviceId]
)
}
return data?["fingerprint"]
} catch {
logIt(.error, "Error fetching chats: \(error.localizedDescription)")
return nil
}
}
}
// MARK: - SenderKey
extension ClientMartinOMEMO: SignalSenderKeyStoreProtocol {
func storeSenderKey(_: Data, address _: MartinOMEMO.SignalAddress?, groupId _: String?) -> Bool {

View file

@ -69,10 +69,22 @@ extension OMEMOSession {
return []
}
}
static func wipe(account: String) {
do {
_ = try Database.shared.dbQueue.write { db in
try OMEMOSession
.filter(Column("account") == account)
.deleteAll(db)
}
} catch {
logIt(.error, "Failed to wipe OMEMO session: \(error)")
}
}
}
// MARK: - Identity
struct OMEMOIdentity: Codable & Equatable, DatabaseValueConvertible {
struct OMEMOIdentity: DBStorable {
static let databaseTableName = "omemo_identities"
let account: String
@ -82,10 +94,28 @@ struct OMEMOIdentity: Codable & Equatable, DatabaseValueConvertible {
let key: Data
let own: Bool
let status: Int
var id: String {
"\(account)_\(name)_\(deviceId)"
}
}
extension OMEMOIdentity {
static func wipe(account: String) {
do {
_ = try Database.shared.dbQueue.write { db in
try OMEMOIdentity
.filter(Column("account") == account)
.deleteAll(db)
}
} catch {
logIt(.error, "Failed to wipe OMEMO identity: \(error)")
}
}
}
// MARK: - PreKey
struct OMEMOPreKey: Codable & Equatable, DatabaseValueConvertible {
struct OMEMOPreKey: DBStorable {
static let databaseTableName = "omemo_pre_keys"
let account: String
@ -93,11 +123,39 @@ struct OMEMOPreKey: Codable & Equatable, DatabaseValueConvertible {
let key: Data
}
extension OMEMOPreKey {
static func wipe(account: String) {
do {
_ = try Database.shared.dbQueue.write { db in
try OMEMOPreKey
.filter(Column("account") == account)
.deleteAll(db)
}
} catch {
logIt(.error, "Failed to wipe OMEMO pre key: \(error)")
}
}
}
// MARK: - SignedPreKey
struct OMEMOSignedPreKey: Codable & Equatable, DatabaseValueConvertible {
struct OMEMOSignedPreKey: DBStorable {
static let databaseTableName = "omemo_signed_pre_keys"
let account: String
let id: Int
let key: Data
}
extension OMEMOSignedPreKey {
static func wipe(account: String) {
do {
_ = try Database.shared.dbQueue.write { db in
try OMEMOSignedPreKey
.filter(Column("account") == account)
.deleteAll(db)
}
} catch {
logIt(.error, "Failed to wipe OMEMO signed pre key: \(error)")
}
}
}