mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Clean
This commit is contained in:
parent
d95df736d5
commit
d32b45f792
|
@ -8,46 +8,35 @@ public final class LokiGroupChatAPI : NSObject {
|
|||
private static let batchCount = 8
|
||||
@objc public static let publicChatMessageType = "network.loki.messenger.publicChat"
|
||||
@objc public static let publicChatID = 1
|
||||
|
||||
private static let tokenCollection = "LokiGroupChatTokenCollection"
|
||||
|
||||
internal static var userDisplayName: String {
|
||||
return SSKEnvironment.shared.contactsManager.displayName(forPhoneIdentifier: userHexEncodedPublicKey) ?? "Anonymous"
|
||||
}
|
||||
|
||||
internal static var identityKeyPair: ECKeyPair {
|
||||
return OWSIdentityManager.shared().identityKeyPair()!
|
||||
}
|
||||
|
||||
private static var userHexEncodedPublicKey: String {
|
||||
return identityKeyPair.hexEncodedPublicKey
|
||||
}
|
||||
|
||||
internal static var userDisplayName: String { return SSKEnvironment.shared.contactsManager.displayName(forPhoneIdentifier: userHexEncodedPublicKey) ?? "Anonymous" }
|
||||
private static var userKeyPair: ECKeyPair { return OWSIdentityManager.shared().identityKeyPair()! }
|
||||
private static var userHexEncodedPublicKey: String { return userKeyPair.hexEncodedPublicKey }
|
||||
|
||||
public enum Error : Swift.Error {
|
||||
case tokenParsingFailed, tokenDecryptionFailed, messageParsingFailed
|
||||
}
|
||||
|
||||
internal static func fetchToken() -> Promise<String> {
|
||||
private static func getTokenFromServer() -> Promise<String> {
|
||||
print("[Loki] Getting group chat auth token.")
|
||||
let url = URL(string: "\(serverURL)/loki/v1/get_challenge?pubKey=\(userHexEncodedPublicKey)")!
|
||||
let request = TSRequest(url: url)
|
||||
return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in
|
||||
guard let json = rawResponse as? JSON, let cipherText64 = json["cipherText64"] as? String, let serverPubKey64 = json["serverPubKey64"] as? String, let cipherText = Data(base64Encoded: cipherText64), var serverPubKey = Data(base64Encoded: serverPubKey64) else {
|
||||
guard let json = rawResponse as? JSON, let base64EncodedChallenge = json["cipherText64"] as? String, let base64EncodedServerPublicKey = json["serverPubKey64"] as? String,
|
||||
let challenge = Data(base64Encoded: base64EncodedChallenge), var serverPublicKey = Data(base64Encoded: base64EncodedServerPublicKey) else {
|
||||
throw Error.tokenParsingFailed
|
||||
}
|
||||
|
||||
// If we have length 33 then the pubkey is prefixed with 05, so we need to remove a byte
|
||||
if (serverPubKey.count == 33) {
|
||||
let hex = serverPubKey.hexadecimalString
|
||||
serverPubKey = Data.data(fromHex: hex.substring(from: 2))!
|
||||
// Discard the "05" prefix if needed
|
||||
if (serverPublicKey.count == 33) {
|
||||
let hexEncodedServerPublicKey = serverPublicKey.hexadecimalString
|
||||
serverPublicKey = Data.data(fromHex: hexEncodedServerPublicKey.substring(from: 2))!
|
||||
}
|
||||
|
||||
// Cipher text has the 16 bit iv prepended to it
|
||||
guard let tokenData = try? DiffieHellman.decrypt(cipherText: cipherText, publicKey: serverPubKey, privateKey: identityKeyPair.privateKey), let token = String(bytes: tokenData, encoding: .utf8), token.count > 0 else {
|
||||
// The challenge is prefixed by the 16 bit IV
|
||||
guard let tokenAsData = try? DiffieHellman.decrypt(challenge, publicKey: serverPublicKey, privateKey: userKeyPair.privateKey),
|
||||
let token = String(bytes: tokenAsData, encoding: .utf8), token.count > 0 else {
|
||||
throw Error.tokenDecryptionFailed
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
||||
}
|
||||
|
@ -61,13 +50,14 @@ public final class LokiGroupChatAPI : NSObject {
|
|||
}
|
||||
|
||||
internal static func getToken() -> Promise<String> {
|
||||
guard let token = storage.dbReadConnection.string(forKey: serverURL, inCollection: tokenCollection), token.count > 0 else {
|
||||
return fetchToken().then { submitToken($0) }.map { token -> String in
|
||||
if let token = storage.dbReadConnection.string(forKey: serverURL, inCollection: tokenCollection), token.count > 0 {
|
||||
return Promise.value(token)
|
||||
} else {
|
||||
return getTokenFromServer().then { submitToken($0) }.map { token -> String in
|
||||
storage.dbReadWriteConnection.setObject(token, forKey: serverURL, inCollection: tokenCollection)
|
||||
return token
|
||||
}
|
||||
}
|
||||
return Promise.value(token)
|
||||
}
|
||||
|
||||
public static func getMessages(for group: UInt) -> Promise<[LokiGroupMessage]> {
|
||||
|
@ -82,7 +72,8 @@ public final class LokiGroupChatAPI : NSObject {
|
|||
}
|
||||
return rawMessages.flatMap { message in
|
||||
guard let annotations = message["annotations"] as? [JSON], let annotation = annotations.first, let value = annotation["value"] as? JSON,
|
||||
let serverID = message["id"] as? UInt, let body = message["text"] as? String, let hexEncodedPublicKey = value["source"] as? String, let displayName = value["from"] as? String, let timestamp = value["timestamp"] as? UInt64 else {
|
||||
let serverID = message["id"] as? UInt, let body = message["text"] as? String, let hexEncodedPublicKey = value["source"] as? String, let displayName = value["from"] as? String,
|
||||
let timestamp = value["timestamp"] as? UInt64 else {
|
||||
print("[Loki] Couldn't parse message for group chat with ID: \(group) from: \(message).")
|
||||
return nil
|
||||
}
|
||||
|
@ -101,11 +92,11 @@ public final class LokiGroupChatAPI : NSObject {
|
|||
request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ]
|
||||
let displayName = userDisplayName
|
||||
return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in
|
||||
// ISO8601DateFormatter doesn't support milliseconds for iOS 10 and below
|
||||
// ISO8601DateFormatter doesn't support milliseconds before iOS 11
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
|
||||
|
||||
guard let json = rawResponse as? JSON, let message = json["data"] as? JSON, let serverID = message["id"] as? UInt, let body = message["text"] as? String, let dateAsString = message["created_at"] as? String, let date = dateFormatter.date(from: dateAsString) else {
|
||||
guard let json = rawResponse as? JSON, let message = json["data"] as? JSON, let serverID = message["id"] as? UInt, let body = message["text"] as? String,
|
||||
let dateAsString = message["created_at"] as? String, let date = dateFormatter.date(from: dateAsString) else {
|
||||
print("[Loki] Couldn't parse messages for group chat with ID: \(group) from: \(rawResponse).")
|
||||
throw Error.messageParsingFailed
|
||||
}
|
||||
|
|
|
@ -2,16 +2,14 @@ import CryptoSwift
|
|||
import Curve25519Kit
|
||||
|
||||
public enum DiffieHellman {
|
||||
// The length of the iv
|
||||
|
||||
public static let ivLength: Int32 = 16;
|
||||
|
||||
public static func encrypt(plainText: Data, symmetricKey: Data) throws -> Data {
|
||||
public static func encrypt(_ plainTextData: Data, using symmetricKey: Data) throws -> Data {
|
||||
let iv = Randomness.generateRandomBytes(ivLength)!
|
||||
let ivBytes = [UInt8](iv)
|
||||
|
||||
let symmetricKeyBytes = [UInt8](symmetricKey)
|
||||
let messageBytes = [UInt8](plainText)
|
||||
|
||||
let messageBytes = [UInt8](plainTextData)
|
||||
let blockMode = CBC(iv: ivBytes)
|
||||
let aes = try AES(key: symmetricKeyBytes, blockMode: blockMode)
|
||||
let cipherText = try aes.encrypt(messageBytes)
|
||||
|
@ -19,25 +17,23 @@ public enum DiffieHellman {
|
|||
return Data(bytes: ivAndCipher, count: ivAndCipher.count)
|
||||
}
|
||||
|
||||
public static func encrypt(plainText: Data, publicKey: Data, privateKey: Data) throws -> Data {
|
||||
public static func encrypt(_ plainTextData: Data, publicKey: Data, privateKey: Data) throws -> Data {
|
||||
let symmetricKey = try Curve25519.generateSharedSecret(fromPublicKey: publicKey, privateKey: privateKey)
|
||||
return try encrypt(plainText: plainText, symmetricKey: symmetricKey)
|
||||
return try encrypt(plainTextData, using: symmetricKey)
|
||||
}
|
||||
|
||||
public static func decrypt(cipherText: Data, symmetricKey: Data) throws -> Data {
|
||||
public static func decrypt(_ encryptedData: Data, using symmetricKey: Data) throws -> Data {
|
||||
let symmetricKeyBytes = [UInt8](symmetricKey)
|
||||
let ivBytes = [UInt8](cipherText[..<ivLength])
|
||||
let cipherBytes = [UInt8](cipherText[ivLength...])
|
||||
|
||||
let ivBytes = [UInt8](encryptedData[..<ivLength])
|
||||
let cipherBytes = [UInt8](encryptedData[ivLength...])
|
||||
let blockMode = CBC(iv: ivBytes)
|
||||
let aes = try AES(key: symmetricKeyBytes, blockMode: blockMode)
|
||||
let decrypted = try aes.decrypt(cipherBytes)
|
||||
|
||||
return Data(bytes: decrypted, count: decrypted.count)
|
||||
}
|
||||
|
||||
public static func decrypt(cipherText: Data, publicKey: Data, privateKey: Data) throws -> Data {
|
||||
public static func decrypt(_ encryptedData: Data, publicKey: Data, privateKey: Data) throws -> Data {
|
||||
let symmetricKey = try Curve25519.generateSharedSecret(fromPublicKey: publicKey, privateKey: privateKey)
|
||||
return try decrypt(cipherText: cipherText, symmetricKey: symmetricKey)
|
||||
return try decrypt(encryptedData, using: symmetricKey)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ private extension String {
|
|||
@objc public func encrypt(message: Data) -> Data? {
|
||||
guard let symmetricKey = symmetricKey else { return nil }
|
||||
do {
|
||||
return try DiffieHellman.encrypt(plainText: message, symmetricKey: symmetricKey)
|
||||
return try DiffieHellman.encrypt(message, using: symmetricKey)
|
||||
} catch {
|
||||
Logger.warn("FallBackSessionCipher: Failed to encrypt message")
|
||||
return nil
|
||||
|
@ -86,7 +86,7 @@ private extension String {
|
|||
@objc public func decrypt(message: Data) -> Data? {
|
||||
guard let symmetricKey = symmetricKey else { return nil }
|
||||
do {
|
||||
return try DiffieHellman.decrypt(cipherText: message, symmetricKey: symmetricKey)
|
||||
return try DiffieHellman.decrypt(message, using: symmetricKey)
|
||||
} catch {
|
||||
Logger.warn("FallBackSessionCipher: Failed to decrypt message")
|
||||
return nil
|
||||
|
|
|
@ -291,7 +291,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
|||
return;
|
||||
}
|
||||
|
||||
// Don't enqueue message for group threads
|
||||
// Don't send any receipts for groups
|
||||
if (message.thread.isGroupThread) { return; }
|
||||
|
||||
if ([self areReadReceiptsEnabled]) {
|
||||
|
|
|
@ -323,10 +323,8 @@ public class TypingIndicatorsImpl: NSObject, TypingIndicators {
|
|||
return
|
||||
}
|
||||
|
||||
// Disable typing indicators on public group chats
|
||||
guard !thread.isGroupThread() else {
|
||||
return
|
||||
}
|
||||
// Don't send any typing indicators for groups
|
||||
guard !thread.isGroupThread() else { return }
|
||||
|
||||
let message = TypingIndicatorMessage(thread: thread, action: action)
|
||||
messageSender.sendPromise(message: message).retainUntilComplete()
|
||||
|
|
Loading…
Reference in a new issue