mv-experiment #1
|
@ -11,6 +11,12 @@ final class ClientMartinOMEMO {
|
||||||
|
|
||||||
init(_ credentials: Credentials) {
|
init(_ credentials: Credentials) {
|
||||||
self.credentials = credentials
|
self.credentials = credentials
|
||||||
|
_ = regenerateKeys(wipe: false)
|
||||||
|
print("ClientMartinOMEMO init")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
print("ClientMartinOMEMO deinit")
|
||||||
}
|
}
|
||||||
|
|
||||||
var signal: (SignalStorage, SignalContext) {
|
var signal: (SignalStorage, SignalContext) {
|
||||||
|
@ -20,25 +26,25 @@ final class ClientMartinOMEMO {
|
||||||
signalStorage.setup(withContext: signalContext)
|
signalStorage.setup(withContext: signalContext)
|
||||||
return (signalStorage, signalContext)
|
return (signalStorage, signalContext)
|
||||||
}
|
}
|
||||||
// func regenerateKeys(wipe: Bool = false) -> Bool {
|
|
||||||
// if wipe {
|
private func regenerateKeys(wipe: Bool = false) -> Bool {
|
||||||
// wipeSignedPreKeys()
|
if wipe {
|
||||||
// }
|
OMEMOSession.wipe(account: credentials.bareJid)
|
||||||
// }
|
OMEMOPreKey.wipe(account: credentials.bareJid)
|
||||||
// if wipe {
|
OMEMOSignedPreKey.wipe(account: credentials.bareJid)
|
||||||
// DBOMEMOStore.instance.wipe(forAccount: context!.sessionObject.userBareJid!)
|
OMEMOIdentity.wipe(account: credentials.bareJid)
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// let hasKeyPair = identityKeyStore.keyPair() != nil
|
let hasKeyPair = keyPair() != nil
|
||||||
// if wipe || identityKeyStore.localRegistrationId() == 0 || !hasKeyPair {
|
if wipe || localRegistrationId() == 0 || !hasKeyPair {
|
||||||
// let regId: UInt32 = signalContext.generateRegistrationId()
|
// let regId: UInt32 = signalContext.generateRegistrationId()
|
||||||
// AccountSettings.omemoRegistrationId(for: context!.sessionObject.userBareJid!, value: regId)
|
// AccountSettings.omemoRegistrationId(for: context!.sessionObject.userBareJid!, value: regId)
|
||||||
//
|
//
|
||||||
// let keyPair = SignalIdentityKeyPair.generateKeyPair(context: signalContext)
|
// let keyPair = SignalIdentityKeyPair.generateKeyPair(context: signalContext)
|
||||||
// if !identityKeyStore.save(identity: SignalAddress(name: context!.sessionObject.userBareJid!.stringValue, deviceId: Int32(identityKeyStore.localRegistrationId())), key: keyPair) {}
|
// if !identityKeyStore.save(identity: SignalAddress(name: context!.sessionObject.userBareJid!.stringValue, deviceId: Int32(identityKeyStore.localRegistrationId())), key: keyPair) {}
|
||||||
// }
|
}
|
||||||
// return true
|
return true
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Session
|
// 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
|
// MARK: - PreKey
|
||||||
extension ClientMartinOMEMO: SignalPreKeyStoreProtocol {
|
extension ClientMartinOMEMO: SignalPreKeyStoreProtocol {
|
||||||
func currentPreKeyId() -> UInt32 {
|
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
|
// MARK: - SenderKey
|
||||||
extension ClientMartinOMEMO: SignalSenderKeyStoreProtocol {
|
extension ClientMartinOMEMO: SignalSenderKeyStoreProtocol {
|
||||||
func storeSenderKey(_: Data, address _: MartinOMEMO.SignalAddress?, groupId _: String?) -> Bool {
|
func storeSenderKey(_: Data, address _: MartinOMEMO.SignalAddress?, groupId _: String?) -> Bool {
|
||||||
|
|
|
@ -69,10 +69,22 @@ extension OMEMOSession {
|
||||||
return []
|
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
|
// MARK: - Identity
|
||||||
struct OMEMOIdentity: Codable & Equatable, DatabaseValueConvertible {
|
struct OMEMOIdentity: DBStorable {
|
||||||
static let databaseTableName = "omemo_identities"
|
static let databaseTableName = "omemo_identities"
|
||||||
|
|
||||||
let account: String
|
let account: String
|
||||||
|
@ -82,10 +94,28 @@ struct OMEMOIdentity: Codable & Equatable, DatabaseValueConvertible {
|
||||||
let key: Data
|
let key: Data
|
||||||
let own: Bool
|
let own: Bool
|
||||||
let status: Int
|
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
|
// MARK: - PreKey
|
||||||
struct OMEMOPreKey: Codable & Equatable, DatabaseValueConvertible {
|
struct OMEMOPreKey: DBStorable {
|
||||||
static let databaseTableName = "omemo_pre_keys"
|
static let databaseTableName = "omemo_pre_keys"
|
||||||
|
|
||||||
let account: String
|
let account: String
|
||||||
|
@ -93,11 +123,39 @@ struct OMEMOPreKey: Codable & Equatable, DatabaseValueConvertible {
|
||||||
let key: Data
|
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
|
// MARK: - SignedPreKey
|
||||||
struct OMEMOSignedPreKey: Codable & Equatable, DatabaseValueConvertible {
|
struct OMEMOSignedPreKey: DBStorable {
|
||||||
static let databaseTableName = "omemo_signed_pre_keys"
|
static let databaseTableName = "omemo_signed_pre_keys"
|
||||||
|
|
||||||
let account: String
|
let account: String
|
||||||
let id: Int
|
let id: Int
|
||||||
let key: Data
|
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)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue