Fixed a crash due to database reentrancy when generating the users blinded public key

This commit is contained in:
Morgan Pretty 2023-04-04 10:18:43 +10:00
parent 65e7009b0a
commit dcae781923
5 changed files with 36 additions and 27 deletions

View file

@ -146,6 +146,7 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
.map { $0.with(recentReactionEmoji: recentReactionEmoji) }
.map { viewModel -> SessionThreadViewModel in
viewModel.populatingCurrentUserBlindedKey(
db,
currentUserBlindedPublicKeyForThisThread: self?.threadData.currentUserBlindedPublicKey
)
}

View file

@ -236,6 +236,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
let userPublicKey: String = getUserHexEncodedPublicKey(db)
let userBlindedKey: String? = SessionThread.getUserHexEncodedBlindedKey(
db,
threadId: thread.id,
threadVariant: thread.variant
)

View file

@ -317,42 +317,46 @@ public extension SessionThread {
}
static func getUserHexEncodedBlindedKey(
_ db: Database? = nil,
threadId: String,
threadVariant: Variant
) -> String? {
guard threadVariant == .openGroup else { return nil }
guard let db: Database = db else {
return Storage.shared.read { db in
getUserHexEncodedBlindedKey(db, threadId: threadId, threadVariant: threadVariant)
}
}
// Retrieve the relevant open group info
struct OpenGroupInfo: Decodable, FetchableRecord {
let publicKey: String
let server: String
}
guard
threadVariant == .openGroup,
let blindingInfo: (edkeyPair: Box.KeyPair?, publicKey: String?, capabilities: Set<Capability.Variant>) = Storage.shared.read({ db in
struct OpenGroupInfo: Decodable, FetchableRecord {
let publicKey: String?
let server: String?
}
let openGroupInfo: OpenGroupInfo? = try OpenGroup
.filter(id: threadId)
.select(.publicKey, .server)
.asRequest(of: OpenGroupInfo.self)
.fetchOne(db)
return (
Identity.fetchUserEd25519KeyPair(db),
openGroupInfo?.publicKey,
(try? Capability
.select(.variant)
.filter(Capability.Columns.openGroupServer == openGroupInfo?.server?.lowercased())
.asRequest(of: Capability.Variant.self)
.fetchSet(db))
.defaulting(to: [])
)
}),
let userEdKeyPair: Box.KeyPair = blindingInfo.edkeyPair,
let publicKey: String = blindingInfo.publicKey,
blindingInfo.capabilities.isEmpty || blindingInfo.capabilities.contains(.blind)
let userEdKeyPair: Box.KeyPair = Identity.fetchUserEd25519KeyPair(db),
let openGroupInfo: OpenGroupInfo = try? OpenGroup
.filter(id: threadId)
.select(.publicKey, .server)
.asRequest(of: OpenGroupInfo.self)
.fetchOne(db)
else { return nil }
// Check the capabilities to ensure the SOGS is blinded (or whether we have no capabilities)
let capabilities: Set<Capability.Variant> = (try? Capability
.select(.variant)
.filter(Capability.Columns.openGroupServer == openGroupInfo.server.lowercased())
.asRequest(of: Capability.Variant.self)
.fetchSet(db))
.defaulting(to: [])
guard capabilities.isEmpty || capabilities.contains(.blind) else { return nil }
let sodium: Sodium = Sodium()
let blindedKeyPair: Box.KeyPair? = sodium.blindedKeyPair(
serverPublicKey: publicKey,
serverPublicKey: openGroupInfo.publicKey,
edKeyPair: userEdKeyPair,
genericHash: sodium.getGenericHash()
)

View file

@ -370,6 +370,7 @@ public extension Message {
let userPublicKey: String = getUserHexEncodedPublicKey(db)
let blindedUserPublicKey: String? = SessionThread
.getUserHexEncodedBlindedKey(
db,
threadId: openGroupId,
threadVariant: .openGroup
)

View file

@ -360,6 +360,7 @@ public extension SessionThreadViewModel {
}
func populatingCurrentUserBlindedKey(
_ db: Database? = nil,
currentUserBlindedPublicKeyForThisThread: String? = nil
) -> SessionThreadViewModel {
return SessionThreadViewModel(
@ -411,6 +412,7 @@ public extension SessionThreadViewModel {
currentUserBlindedPublicKey: (
currentUserBlindedPublicKeyForThisThread ??
SessionThread.getUserHexEncodedBlindedKey(
db,
threadId: self.threadId,
threadVariant: self.threadVariant
)