Swiftgram/submodules/TelegramCore/Sources/CreateSecretChat.swift
2019-11-01 17:11:12 +04:00

49 lines
2.5 KiB
Swift

import Foundation
import Postbox
import SwiftSignalKit
import TelegramApi
import MtProtoKit
public enum CreateSecretChatError {
case generic
}
public func createSecretChat(account: Account, peerId: PeerId) -> Signal<PeerId, CreateSecretChatError> {
return account.postbox.transaction { transaction -> Signal<PeerId, CreateSecretChatError> in
if let peer = transaction.getPeer(peerId), let inputUser = apiInputUser(peer) {
return validatedEncryptionConfig(postbox: account.postbox, network: account.network)
|> mapError { _ -> CreateSecretChatError in return .generic }
|> mapToSignal { config -> Signal<PeerId, CreateSecretChatError> in
let aBytes = malloc(256)!
let _ = SecRandomCopyBytes(nil, 256, aBytes.assumingMemoryBound(to: UInt8.self))
let a = MemoryBuffer(memory: aBytes, capacity: 256, length: 256, freeWhenDone: true)
var gValue: Int32 = config.g.byteSwapped
let g = Data(bytes: &gValue, count: 4)
let p = config.p.makeData()
let aData = a.makeData()
let ga = MTExp(account.network.encryptionProvider, g, aData, p)!
if !MTCheckIsSafeGAOrB(account.network.encryptionProvider, ga, p) {
return .fail(.generic)
}
return account.network.request(Api.functions.messages.requestEncryption(userId: inputUser, randomId: Int32(bitPattern: arc4random()), gA: Buffer(data: ga)))
|> mapError { _ -> CreateSecretChatError in
return .generic
}
|> mapToSignal { result -> Signal<PeerId, CreateSecretChatError> in
return account.postbox.transaction { transaction -> PeerId in
updateSecretChat(encryptionProvider: account.network.encryptionProvider, accountPeerId: account.peerId, transaction: transaction, chat: result, requestData: SecretChatRequestData(g: config.g, p: config.p, a: a))
return result.peerId
} |> mapError { _ -> CreateSecretChatError in return .generic }
}
}
} else {
return .fail(.generic)
}
} |> mapError { _ -> CreateSecretChatError in return .generic } |> switchToLatest
}