retrieve messages authenticated for 1-1 chats

pull/622/head
Ryan Zhao 4 years ago
parent f48cdd02ee
commit 0b0f0a3787

@ -103,7 +103,7 @@ public final class ClosedGroupPoller : NSObject {
// randomElement() uses the system's default random generator, which is cryptographically secure
guard let snode = swarm.randomElement() else { return Promise(error: Error.insufficientSnodes) }
guard let self = self, self.isPolling(for: groupPublicKey) else { return Promise(error: Error.pollingCanceled) }
return SnodeAPI.getRawMessages(from: snode, associatedWith: groupPublicKey).map2 {
return SnodeAPI.getRawMessagesUnauthenticated(from: snode, associatedWith: groupPublicKey).map2 {
let (rawMessages, lastRawMessage) = SnodeAPI.parseRawMessagesResponse($0, from: snode, associatedWith: groupPublicKey)
return (snode, rawMessages, lastRawMessage)

@ -22,6 +22,11 @@ public final class SnodeAPI : NSObject {
public static var clockOffset: Int64 = 0
/// - Note: Should only be accessed from `Threading.workQueue` to avoid race conditions.
public static var swarmCache: [String:Set<Snode>] = [:]
// MARK: Namespaces
private static let defaultNamespace = 0
private static let unauthenticatedNamespace = -10
private static let configNamespace = 5
// MARK: Settings
private static let maxRetryCount: UInt = 8
@ -391,36 +396,61 @@ public final class SnodeAPI : NSObject {
}
public static func getRawMessages(from snode: Snode, associatedWith publicKey: String) -> RawResponsePromise {
let (promise, seal) = RawResponsePromise.pending()
Threading.workQueue.async {
getMessagesWithAuthentication(from: snode, associatedWith: publicKey).done2 { seal.fulfill($0) }.catch2 { seal.reject($0) }
}
return promise
}
public static func getRawMessagesUnauthenticated(from snode: Snode, associatedWith publicKey: String) -> RawResponsePromise {
let (promise, seal) = RawResponsePromise.pending()
Threading.workQueue.async {
getMessagesInternal(from: snode, associatedWith: publicKey).done2 { seal.fulfill($0) }.catch2 { seal.reject($0) }
}
return promise
}
private static func getMessagesInternal(from snode: Snode, associatedWith publicKey: String) -> RawResponsePromise {
private static func getMessagesWithAuthentication(from snode: Snode, associatedWith publicKey: String) -> RawResponsePromise {
let storage = SNSnodeKitConfiguration.shared.storage
// NOTE: All authentication logic is currently commented out, the reason being that we can't currently support
// NOTE: All authentication logic is only apply to 1-1 chats, the reason being that we can't currently support
// it yet for closed groups. The Storage Server requires an ed25519 key pair, but we don't have that for our
// closed groups.
// guard let userED25519KeyPair = storage.getUserED25519KeyPair() else { return Promise(error: Error.noKeyPair) }
guard let userED25519KeyPair = storage.getUserED25519KeyPair() else { return Promise(error: Error.noKeyPair) }
// Get last message hash
storage.pruneLastMessageHashInfoIfExpired(for: snode, associatedWith: publicKey)
let lastHash = storage.getLastMessageHash(for: snode, associatedWith: publicKey) ?? ""
// Construct signature
// let timestamp = UInt64(Int64(NSDate.millisecondTimestamp()) + SnodeAPI.clockOffset)
// let ed25519PublicKey = userED25519KeyPair.publicKey.toHexString()
// let verificationData = ("retrieve" + String(timestamp)).data(using: String.Encoding.utf8)!
// let signature = sodium.sign.signature(message: Bytes(verificationData), secretKey: userED25519KeyPair.secretKey)!
let timestamp = UInt64(Int64(NSDate.millisecondTimestamp()) + SnodeAPI.clockOffset)
let ed25519PublicKey = userED25519KeyPair.publicKey.toHexString()
let verificationData = ("retrieve" + String(timestamp)).data(using: String.Encoding.utf8)!
let signature = sodium.sign.signature(message: Bytes(verificationData), secretKey: userED25519KeyPair.secretKey)!
// Make the request
let parameters: JSON = [
"pubKey" : Features.useTestnet ? publicKey.removing05PrefixIfNeeded() : publicKey,
"namespace": defaultNamespace,
"lastHash" : lastHash,
"timestamp" : timestamp,
"pubkey_ed25519" : ed25519PublicKey,
"signature" : signature.toBase64()
]
return invoke(.getMessages, on: snode, associatedWith: publicKey, parameters: parameters)
}
private static func getMessagesInternal(from snode: Snode, associatedWith publicKey: String) -> RawResponsePromise {
let storage = SNSnodeKitConfiguration.shared.storage
// Get last message hash
storage.pruneLastMessageHashInfoIfExpired(for: snode, associatedWith: publicKey)
let lastHash = storage.getLastMessageHash(for: snode, associatedWith: publicKey) ?? ""
// Make the request
let parameters: JSON = [
"pubKey" : Features.useTestnet ? publicKey.removing05PrefixIfNeeded() : publicKey,
"namespace": unauthenticatedNamespace,
"lastHash" : lastHash,
// "timestamp" : timestamp,
// "pubkey_ed25519" : ed25519PublicKey,
// "signature" : signature.toBase64()!
]
return invoke(.getMessages, on: snode, associatedWith: publicKey, parameters: parameters)
}

Loading…
Cancel
Save