mirror of https://github.com/oxen-io/session-ios
Serialize RefreshKeyOperation
TODO -[] rotate signed prekey job -[] verify current prekey w/ server -[] create keyspull/1/head
parent
01811a4891
commit
286d3c8ce9
@ -1 +1 @@
|
||||
Subproject commit e9fb539a0061d7e9f87ba48a724f99092232b41b
|
||||
Subproject commit af45234a3daa09e47012af11feec181dfcec1d55
|
@ -0,0 +1,29 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PromiseKit
|
||||
|
||||
// TODO define actual type, and validate length
|
||||
public typealias IdentityKey = Data
|
||||
|
||||
@objc(SSKAccountManager)
|
||||
public class AccountManager: NSObject {
|
||||
|
||||
static var shared = AccountManager()
|
||||
|
||||
private let serviceSocket: ServiceSocket
|
||||
|
||||
override init() {
|
||||
self.serviceSocket = ServiceRestSocket()
|
||||
}
|
||||
|
||||
public func getPreKeysCount() -> Promise<Int> {
|
||||
return serviceSocket.getAvailablePreKeys()
|
||||
}
|
||||
|
||||
public func setPreKeys(identityKey: IdentityKey, signedPreKeyRecord: SignedPreKeyRecord, preKeyRecords: [PreKeyRecord]) -> Promise<Void> {
|
||||
return serviceSocket.registerPreKeys(identityKey: identityKey, signedPreKeyRecord: signedPreKeyRecord, preKeyRecords: preKeyRecords)
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PromiseKit
|
||||
|
||||
// We generate 100 one-time prekeys at a time. We should replenish
|
||||
// whenever ~2/3 of them have been consumed.
|
||||
let kEphemeralPreKeysMinimumCount: UInt = 35
|
||||
|
||||
@objc(SSKRefreshPreKeysOperation)
|
||||
public class RefreshPreKeysOperation: OWSOperation {
|
||||
|
||||
private var tsAccountManager: TSAccountManager {
|
||||
return TSAccountManager.sharedInstance()
|
||||
}
|
||||
|
||||
private var accountManager: AccountManager {
|
||||
return AccountManager.shared
|
||||
}
|
||||
private var primaryStorage: OWSPrimaryStorage {
|
||||
return OWSPrimaryStorage.shared()
|
||||
}
|
||||
|
||||
private var identityKeyManager: OWSIdentityManager {
|
||||
return OWSIdentityManager.shared()
|
||||
}
|
||||
|
||||
public override func run() {
|
||||
Logger.debug("")
|
||||
|
||||
guard tsAccountManager.isRegistered() else {
|
||||
Logger.debug("skipping - not registered")
|
||||
return
|
||||
}
|
||||
|
||||
firstly {
|
||||
self.accountManager.getPreKeysCount()
|
||||
}.then(on: DispatchQueue.global()) { preKeysCount -> Promise<Void> in
|
||||
Logger.debug("preKeysCount: \(preKeysCount)")
|
||||
guard preKeysCount < kEphemeralPreKeysMinimumCount || self.primaryStorage.currentSignedPrekeyId() == nil else {
|
||||
Logger.debug("Available keys sufficient: \(preKeysCount)")
|
||||
return Promise(value: ())
|
||||
}
|
||||
|
||||
let identityKey: Data = self.identityKeyManager.identityKeyPair()!.publicKey
|
||||
let signedPreKeyRecord: SignedPreKeyRecord = self.primaryStorage.generateRandomSignedRecord()
|
||||
let preKeyRecords: [PreKeyRecord] = self.primaryStorage.generatePreKeyRecords()
|
||||
|
||||
return self.accountManager.setPreKeys(identityKey: identityKey, signedPreKeyRecord: signedPreKeyRecord, preKeyRecords: preKeyRecords).then { () -> Void in
|
||||
signedPreKeyRecord.markAsAcceptedByService()
|
||||
self.primaryStorage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord)
|
||||
self.primaryStorage.setCurrentSignedPrekeyId(signedPreKeyRecord.id)
|
||||
self.primaryStorage.storePreKeyRecords(preKeyRecords)
|
||||
|
||||
TSPreKeyManager.clearSignedPreKeyRecords()
|
||||
}
|
||||
}.then { () -> Void in
|
||||
Logger.debug("done")
|
||||
self.reportSuccess()
|
||||
}.catch { error in
|
||||
self.reportError(error)
|
||||
}.retainUntilComplete()
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PromiseKit
|
||||
|
||||
protocol ServiceSocket {
|
||||
func getAvailablePreKeys() -> Promise<Int>
|
||||
func registerPreKeys(identityKey: IdentityKey, signedPreKeyRecord: SignedPreKeyRecord, preKeyRecords: [PreKeyRecord]) -> Promise<Void>
|
||||
}
|
||||
|
||||
class ServiceRestSocket: ServiceSocket {
|
||||
|
||||
var networkManager: TSNetworkManager {
|
||||
return TSNetworkManager.shared()
|
||||
}
|
||||
|
||||
func unexpectedServerResponseError() -> Error {
|
||||
return OWSErrorMakeUnableToProcessServerResponseError()
|
||||
}
|
||||
|
||||
func getAvailablePreKeys() -> Promise<Int> {
|
||||
Logger.debug("")
|
||||
|
||||
let (promise, fulfill, reject) = Promise<Int>.pending()
|
||||
|
||||
let request = OWSRequestFactory.availablePreKeysCountRequest()
|
||||
networkManager.makeRequest(request,
|
||||
success: { (_, responseObject) in
|
||||
Logger.debug("got response")
|
||||
guard let params = ParamParser(responseObject: responseObject) else {
|
||||
reject(self.unexpectedServerResponseError())
|
||||
return
|
||||
}
|
||||
|
||||
let count: Int
|
||||
do {
|
||||
count = try params.required(key: "count")
|
||||
} catch {
|
||||
reject(error)
|
||||
return
|
||||
}
|
||||
|
||||
fulfill(count)
|
||||
},
|
||||
failure: { (_, error) in
|
||||
Logger.debug("error: \(error)")
|
||||
reject(error)
|
||||
})
|
||||
return promise
|
||||
}
|
||||
|
||||
func registerPreKeys(identityKey: IdentityKey, signedPreKeyRecord: SignedPreKeyRecord, preKeyRecords: [PreKeyRecord]) -> Promise<Void> {
|
||||
Logger.debug("")
|
||||
|
||||
let (promise, fulfill, reject) = Promise<Void>.pending()
|
||||
let request = OWSRequestFactory.registerPrekeysRequest(withPrekeyArray: preKeyRecords, identityKey: identityKey, signedPreKey: signedPreKeyRecord)
|
||||
|
||||
networkManager.makeRequest(request,
|
||||
success: { (_, _) in
|
||||
Logger.debug("success")
|
||||
fulfill(())
|
||||
|
||||
},
|
||||
failure: { (_, error) in
|
||||
Logger.debug("error: \(error)")
|
||||
reject(error)
|
||||
})
|
||||
return promise
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue