Skip to content

Commit 7dd2593

Browse files
Partial fix for issue with publishing invalid bundles #725 #732
1 parent c8f8f07 commit 7dd2593

File tree

5 files changed

+72
-10
lines changed

5 files changed

+72
-10
lines changed

ChatSecure/Classes/Controllers/Errors.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ extension EncryptionError: ChatSecureErrorProtocol {
111111
case serviceUnavailable = 1004
112112
}
113113

114+
public enum OMEMOBundleError: Error {
115+
case unknown
116+
case notFound
117+
case invalid
118+
case keyGeneration
119+
}
120+
114121
extension OTRXMPPXMLError: ChatSecureErrorProtocol {
115122
public func code() -> Int {
116123
return self.rawValue

ChatSecure/Classes/Controllers/OTRAccountSignalEncryptionManager.swift

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,16 @@ extension OTRAccountSignalEncryptionManager {
6767
/**
6868
* This creates all the information necessary to publish a 'bundle' to your XMPP server via PEP. It generates prekeys 0 to 99.
6969
*/
70-
public func generateOutgoingBundle(_ preKeyCount:UInt) -> OTROMEMOBundleOutgoing? {
70+
public func generateOutgoingBundle(_ preKeyCount:UInt) throws -> OTROMEMOBundleOutgoing {
7171

7272
guard let signedPreKey = self.generateRandomSignedPreKey(), let data = signedPreKey.serializedData() else {
73-
return nil
73+
throw OMEMOBundleError.keyGeneration
7474
}
75-
_ = self.storage.storeSignedPreKey(data, signedPreKeyId: signedPreKey.preKeyId())
7675

7776
let publicIdentityKey = self.storage.getIdentityKeyPair().publicKey
7877
let deviceId = self.registrationId
7978
guard let preKeys = self.generatePreKeys(1, count: preKeyCount) else {
80-
return nil
79+
throw OMEMOBundleError.keyGeneration
8180
}
8281

8382
var preKeyDict = [UInt32:Data]()
@@ -86,6 +85,20 @@ extension OTRAccountSignalEncryptionManager {
8685
}
8786

8887
let bundle = OTROMEMOBundle(deviceId: deviceId, publicIdentityKey: publicIdentityKey, signedPublicPreKey: signedPreKey.keyPair().publicKey, signedPreKeyId: signedPreKey.preKeyId(), signedPreKeySignature: signedPreKey.signature())
88+
89+
do {
90+
if let preKey = preKeys.first {
91+
let _ = try SignalPreKeyBundle(registrationId: 0, deviceId: bundle.deviceId, preKeyId: preKey.preKeyId(), preKeyPublic: preKey.keyPair().publicKey, signedPreKeyId: bundle.signedPreKeyId, signedPreKeyPublic: bundle.signedPublicPreKey, signature: bundle.signedPreKeySignature, identityKey: bundle.publicIdentityKey)
92+
} else {
93+
DDLogError("Error testing outgoing bundle")
94+
throw OMEMOBundleError.invalid
95+
}
96+
} catch let error {
97+
DDLogError("Error creating outgoing bundle: \(error)")
98+
throw OMEMOBundleError.invalid
99+
}
100+
101+
_ = self.storage.storeSignedPreKey(data, signedPreKeyId: signedPreKey.preKeyId())
89102
return OTROMEMOBundleOutgoing(bundle: bundle, preKeys: preKeyDict)
90103
}
91104

@@ -96,7 +109,7 @@ extension OTRAccountSignalEncryptionManager {
96109
let deviceId = Int32(bundle.bundle.deviceId)
97110
let incomingAddress = SignalAddress(name: name.lowercased(), deviceId: deviceId)
98111
let sessionBuilder = SignalSessionBuilder(address: incomingAddress, context: self.signalContext)
99-
let preKeyBundle = SignalPreKeyBundle(registrationId: 0, deviceId: bundle.bundle.deviceId, preKeyId: bundle.preKeyId, preKeyPublic: bundle.preKeyData as Data, signedPreKeyId: bundle.bundle.signedPreKeyId, signedPreKeyPublic: bundle.bundle.signedPublicPreKey as Data, signature: bundle.bundle.signedPreKeySignature as Data, identityKey: bundle.bundle.publicIdentityKey as Data)
112+
let preKeyBundle = try SignalPreKeyBundle(registrationId: 0, deviceId: bundle.bundle.deviceId, preKeyId: bundle.preKeyId, preKeyPublic: bundle.preKeyData, signedPreKeyId: bundle.bundle.signedPreKeyId, signedPreKeyPublic: bundle.bundle.signedPublicPreKey, signature: bundle.bundle.signedPreKeySignature, identityKey: bundle.bundle.publicIdentityKey)
100113

101114
return try sessionBuilder.processPreKeyBundle(preKeyBundle)
102115
}

ChatSecure/Classes/Controllers/OTROMEMOSignalCoordinator.swift

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,10 +516,13 @@ extension OTROMEMOSignalCoordinator: OMEMOModuleDelegate {
516516
public func omemo(_ omemo: OMEMOModule, fetchedBundle bundle: OMEMOBundle, from fromJID: XMPPJID, responseIq: XMPPIQ, outgoingIq: XMPPIQ) {
517517

518518
if (self.isOurJID(fromJID) && bundle.deviceId == self.signalEncryptionManager.registrationId) {
519+
DDLogVerbose("fetchedOurOwnBundle: \(responseIq) \(outgoingIq)")
520+
519521
//We fetched our own bundle
520522
if let ourDatabaseBundle = self.fetchMyBundle() {
521523
//This bundle doesn't have the correct identity key. Something has gone wrong and we should republish
522524
if ourDatabaseBundle.identityKey != bundle.identityKey {
525+
DDLogError("Bundle identityKeys do not match! \(ourDatabaseBundle.identityKey) vs \(bundle.identityKey)")
523526
omemo.publishBundle(ourDatabaseBundle, elementId: nil)
524527
}
525528
}
@@ -617,8 +620,35 @@ extension OTROMEMOSignalCoordinator:OMEMOStorageDelegate {
617620

618621
//Always returns most complete bundle with correct count of prekeys
619622
public func fetchMyBundle() -> OMEMOBundle? {
623+
var _bundle: OTROMEMOBundleOutgoing? = nil
620624

621-
guard let bundle = self.signalEncryptionManager.storage.fetchOurExistingBundle() ?? self.signalEncryptionManager.generateOutgoingBundle(self.preKeyCount) else {
625+
do {
626+
_bundle = try signalEncryptionManager.storage.fetchOurExistingBundle()
627+
628+
} catch let omemoError as OMEMOBundleError {
629+
switch omemoError {
630+
case .invalid:
631+
DDLogError("Found invalid stored bundle!")
632+
// delete???
633+
break
634+
default:
635+
break
636+
}
637+
} catch let error {
638+
DDLogError("Other error fetching bundle! \(error)")
639+
}
640+
let maxTries = 5
641+
var tries = 0
642+
while _bundle == nil && tries < maxTries {
643+
tries = tries + 1
644+
do {
645+
_bundle = try self.signalEncryptionManager.generateOutgoingBundle(self.preKeyCount)
646+
} catch let error {
647+
DDLogError("Error generating bundle! Try #\(tries)/\(maxTries) \(error)")
648+
}
649+
}
650+
guard let bundle = _bundle else {
651+
DDLogError("Could not fetch or generate valid bundle!")
622652
return nil
623653
}
624654

ChatSecure/Classes/Controllers/OTRSignalStorageManager.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ open class OTRSignalStorageManager: NSObject {
159159

160160
- return: A complete outgoing bundle.
161161
*/
162-
open func fetchOurExistingBundle() -> OTROMEMOBundleOutgoing? {
162+
open func fetchOurExistingBundle() throws -> OTROMEMOBundleOutgoing {
163163
var simpleBundle:OTROMEMOBundle? = nil
164164
//Fetch and create the base bundle
165165
self.databaseConnection.read { (transaction) in
@@ -178,7 +178,7 @@ open class OTRSignalStorageManager: NSObject {
178178
}
179179

180180
guard let bundle = simpleBundle else {
181-
return nil
181+
throw OMEMOBundleError.notFound
182182
}
183183

184184
//Gather pieces of outgoing bundle
@@ -198,6 +198,18 @@ open class OTRSignalStorageManager: NSObject {
198198
}
199199
})
200200

201+
do {
202+
if let preKey = preKeys.first, let preKeyData = preKey.keyData {
203+
let _ = try SignalPreKeyBundle(registrationId: 0, deviceId: bundle.deviceId, preKeyId: preKey.keyId, preKeyPublic: preKeyData, signedPreKeyId: bundle.signedPreKeyId, signedPreKeyPublic: bundle.signedPublicPreKey, signature: bundle.signedPreKeySignature, identityKey: bundle.publicIdentityKey)
204+
} else {
205+
DDLogError("Error fetching outgoing bundle: no prekeys")
206+
throw OMEMOBundleError.invalid
207+
}
208+
} catch let error {
209+
DDLogError("Error fetching outgoing bundle: \(error)")
210+
throw error
211+
}
212+
201213
return OTROMEMOBundleOutgoing(bundle: bundle, preKeys: preKeyDict as [UInt32 : Data])
202214
}
203215

ChatSecure/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>CFBundlePackageType</key>
1616
<string>APPL</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>4.0.6</string>
18+
<string>4.0.7</string>
1919
<key>CFBundleSignature</key>
2020
<string>????</string>
2121
<key>CFBundleURLTypes</key>
@@ -35,7 +35,7 @@
3535
</dict>
3636
</array>
3737
<key>CFBundleVersion</key>
38-
<string>74</string>
38+
<string>75</string>
3939
<key>FacebookAppID</key>
4040
<string>447241325394334</string>
4141
<key>FacebookDisplayName</key>

0 commit comments

Comments
 (0)