Fix onion request layout

pull/148/head
gmbnt 6 years ago
parent 9c9049774e
commit d54c9c6175

@ -44,13 +44,16 @@ extension OnionRequestAPI {
} }
/// Encrypts `payload` for `snode` and returns the result. Use this to build the core of an onion request. /// Encrypts `payload` for `snode` and returns the result. Use this to build the core of an onion request.
internal static func encrypt(_ payload: Data, forTargetSnode snode: LokiAPITarget) -> Promise<EncryptionResult> { internal static func encrypt(_ payload: JSON, forTargetSnode snode: LokiAPITarget) -> Promise<EncryptionResult> {
let (promise, seal) = Promise<EncryptionResult>.pending() let (promise, seal) = Promise<EncryptionResult>.pending()
getQueue().async { getQueue().async {
let parameters: JSON = [ "body" : payload.base64EncodedString(), "headers" : "" ]
do { do {
guard JSONSerialization.isValidJSONObject(parameters) else { return seal.reject(Error.invalidJSON) } guard JSONSerialization.isValidJSONObject(payload) else { return seal.reject(Error.invalidJSON) }
let plaintext = try JSONSerialization.data(withJSONObject: parameters, options: []) let payloadAsData = try JSONSerialization.data(withJSONObject: payload, options: [])
let payloadAsString = String(data: payloadAsData, encoding: .utf8)! // Snodes only accept this as a string
let wrapper: JSON = [ "body" : payloadAsString, "headers" : "" ]
guard JSONSerialization.isValidJSONObject(wrapper) else { return seal.reject(Error.invalidJSON) }
let plaintext = try JSONSerialization.data(withJSONObject: wrapper, options: [])
let result = try encrypt(plaintext, forSnode: snode) let result = try encrypt(plaintext, forSnode: snode)
seal.fulfill(result) seal.fulfill(result)
} catch (let error) { } catch (let error) {

@ -65,7 +65,7 @@ internal enum OnionRequestAPI {
internal typealias Path = [LokiAPITarget] internal typealias Path = [LokiAPITarget]
// MARK: Onion Building Result // MARK: Onion Building Result
private typealias OnionBuildingResult = (guardSnode: LokiAPITarget, encryptionResult: EncryptionResult, targetSnodeSymmetricKey: Data) private typealias OnionBuildingResult = (guardSnode: LokiAPITarget, finalEncryptionResult: EncryptionResult, targetSnodeSymmetricKey: Data)
// MARK: Private API // MARK: Private API
private static func execute(_ verb: HTTPVerb, _ url: String, parameters: JSON? = nil, timeout: TimeInterval = OnionRequestAPI.timeout) -> Promise<JSON> { private static func execute(_ verb: HTTPVerb, _ url: String, parameters: JSON? = nil, timeout: TimeInterval = OnionRequestAPI.timeout) -> Promise<JSON> {
@ -215,7 +215,7 @@ internal enum OnionRequestAPI {
} }
/// Builds an onion around `payload` and returns the result. /// Builds an onion around `payload` and returns the result.
private static func buildOnion(around payload: Data, targetedAt snode: LokiAPITarget) -> Promise<OnionBuildingResult> { private static func buildOnion(around payload: JSON, targetedAt snode: LokiAPITarget) -> Promise<OnionBuildingResult> {
var guardSnode: LokiAPITarget! var guardSnode: LokiAPITarget!
var targetSnodeSymmetricKey: Data! // Needed by invoke(_:on:with:) to decrypt the response sent back by the target snode var targetSnodeSymmetricKey: Data! // Needed by invoke(_:on:with:) to decrypt the response sent back by the target snode
var encryptionResult: EncryptionResult! var encryptionResult: EncryptionResult!
@ -250,22 +250,15 @@ internal enum OnionRequestAPI {
internal static func invoke(_ method: LokiAPITarget.Method, on snode: LokiAPITarget, with parameters: JSON) -> Promise<Any> { internal static func invoke(_ method: LokiAPITarget.Method, on snode: LokiAPITarget, with parameters: JSON) -> Promise<Any> {
let (promise, seal) = Promise<Any>.pending() let (promise, seal) = Promise<Any>.pending()
workQueue.async { workQueue.async {
let parameters: JSON = [ "method" : method.rawValue, "params" : parameters ] let payload: JSON = [ "method" : method.rawValue, "params" : parameters ]
let payload: Data
do {
guard JSONSerialization.isValidJSONObject(parameters) else { return seal.reject(Error.invalidJSON) }
payload = try JSONSerialization.data(withJSONObject: parameters, options: [])
} catch (let error) {
return seal.reject(error)
}
buildOnion(around: payload, targetedAt: snode).done(on: workQueue) { intermediate in buildOnion(around: payload, targetedAt: snode).done(on: workQueue) { intermediate in
let guardSnode = intermediate.guardSnode let guardSnode = intermediate.guardSnode
let url = "\(guardSnode.address):\(guardSnode.port)/onion_req" let url = "\(guardSnode.address):\(guardSnode.port)/onion_req"
let encryptionResult = intermediate.encryptionResult let finalEncryptionResult = intermediate.finalEncryptionResult
let onion = encryptionResult.ciphertext let onion = finalEncryptionResult.ciphertext
let parameters: JSON = [ let parameters: JSON = [
"ciphertext" : onion.base64EncodedString(), "ciphertext" : onion.base64EncodedString(),
"ephemeral_key" : encryptionResult.ephemeralPublicKey.toHexString() "ephemeral_key" : finalEncryptionResult.ephemeralPublicKey.toHexString()
] ]
let targetSnodeSymmetricKey = intermediate.targetSnodeSymmetricKey let targetSnodeSymmetricKey = intermediate.targetSnodeSymmetricKey
execute(.post, url, parameters: parameters).done(on: workQueue) { rawResponse in execute(.post, url, parameters: parameters).done(on: workQueue) { rawResponse in

Loading…
Cancel
Save