|
|
@ -12,6 +12,15 @@ public enum OWSUDError: Error {
|
|
|
|
case invalidData(description: String)
|
|
|
|
case invalidData(description: String)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
|
|
|
|
public enum OWSUDCertificateExpirationPolicy: Int {
|
|
|
|
|
|
|
|
// We want to try to rotate the sender certificate
|
|
|
|
|
|
|
|
// on a frequent basis, but we don't want to block
|
|
|
|
|
|
|
|
// sending on this.
|
|
|
|
|
|
|
|
case strict
|
|
|
|
|
|
|
|
case permissive
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
@objc
|
|
|
|
public enum UnidentifiedAccessMode: Int {
|
|
|
|
public enum UnidentifiedAccessMode: Int {
|
|
|
|
case unknown
|
|
|
|
case unknown
|
|
|
@ -104,6 +113,8 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
|
|
|
private let kUDCollection = "kUDCollection"
|
|
|
|
private let kUDCollection = "kUDCollection"
|
|
|
|
private let kUDCurrentSenderCertificateKey_Production = "kUDCurrentSenderCertificateKey_Production"
|
|
|
|
private let kUDCurrentSenderCertificateKey_Production = "kUDCurrentSenderCertificateKey_Production"
|
|
|
|
private let kUDCurrentSenderCertificateKey_Staging = "kUDCurrentSenderCertificateKey_Staging"
|
|
|
|
private let kUDCurrentSenderCertificateKey_Staging = "kUDCurrentSenderCertificateKey_Staging"
|
|
|
|
|
|
|
|
private let kUDCurrentSenderCertificateDateKey_Production = "kUDCurrentSenderCertificateDateKey_Production"
|
|
|
|
|
|
|
|
private let kUDCurrentSenderCertificateDateKey_Staging = "kUDCurrentSenderCertificateDateKey_Staging"
|
|
|
|
private let kUDUnrestrictedAccessKey = "kUDUnrestrictedAccessKey"
|
|
|
|
private let kUDUnrestrictedAccessKey = "kUDUnrestrictedAccessKey"
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: Recipient State
|
|
|
|
// MARK: Recipient State
|
|
|
@ -128,12 +139,16 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Any error is silently ignored on startup.
|
|
|
|
// Any error is silently ignored on startup.
|
|
|
|
self.ensureSenderCertificate().retainUntilComplete()
|
|
|
|
self.ensureSenderCertificate(certificateExpirationPolicy: .strict).retainUntilComplete()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NotificationCenter.default.addObserver(self,
|
|
|
|
NotificationCenter.default.addObserver(self,
|
|
|
|
selector: #selector(registrationStateDidChange),
|
|
|
|
selector: #selector(registrationStateDidChange),
|
|
|
|
name: .RegistrationStateDidChange,
|
|
|
|
name: .RegistrationStateDidChange,
|
|
|
|
object: nil)
|
|
|
|
object: nil)
|
|
|
|
|
|
|
|
NotificationCenter.default.addObserver(self,
|
|
|
|
|
|
|
|
selector: #selector(didBecomeActive),
|
|
|
|
|
|
|
|
name: NSNotification.Name.OWSApplicationDidBecomeActive,
|
|
|
|
|
|
|
|
object: nil)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
@objc
|
|
|
@ -141,7 +156,20 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
|
|
|
AssertIsOnMainThread()
|
|
|
|
AssertIsOnMainThread()
|
|
|
|
|
|
|
|
|
|
|
|
// Any error is silently ignored
|
|
|
|
// Any error is silently ignored
|
|
|
|
ensureSenderCertificate().retainUntilComplete()
|
|
|
|
ensureSenderCertificate(certificateExpirationPolicy: .strict).retainUntilComplete()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@objc func didBecomeActive() {
|
|
|
|
|
|
|
|
AssertIsOnMainThread()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AppReadiness.runNowOrWhenAppDidBecomeReady {
|
|
|
|
|
|
|
|
guard TSAccountManager.isRegistered() else {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Any error is silently ignored on startup.
|
|
|
|
|
|
|
|
self.ensureSenderCertificate(certificateExpirationPolicy: .strict).retainUntilComplete()
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: -
|
|
|
|
// MARK: -
|
|
|
@ -308,11 +336,21 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
|
|
|
#if DEBUG
|
|
|
|
#if DEBUG
|
|
|
|
@objc
|
|
|
|
@objc
|
|
|
|
public func hasSenderCertificate() -> Bool {
|
|
|
|
public func hasSenderCertificate() -> Bool {
|
|
|
|
return senderCertificate() != nil
|
|
|
|
return senderCertificate(certificateExpirationPolicy: .permissive) != nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
private func senderCertificate() -> SMKSenderCertificate? {
|
|
|
|
private func senderCertificate(certificateExpirationPolicy: OWSUDCertificateExpirationPolicy) -> SMKSenderCertificate? {
|
|
|
|
|
|
|
|
if certificateExpirationPolicy == .strict {
|
|
|
|
|
|
|
|
guard let certificateDate = dbConnection.object(forKey: senderCertificateDateKey(), inCollection: kUDCollection) as? Date else {
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
guard certificateDate.timeIntervalSinceNow < kDayInterval else {
|
|
|
|
|
|
|
|
// Discard certificates that we obtained more than 24 hours ago.
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
guard let certificateData = dbConnection.object(forKey: senderCertificateKey(), inCollection: kUDCollection) as? Data else {
|
|
|
|
guard let certificateData = dbConnection.object(forKey: senderCertificateKey(), inCollection: kUDCollection) as? Data else {
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -333,6 +371,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func setSenderCertificate(_ certificateData: Data) {
|
|
|
|
func setSenderCertificate(_ certificateData: Data) {
|
|
|
|
|
|
|
|
dbConnection.setObject(Date(), forKey: senderCertificateDateKey(), inCollection: kUDCollection)
|
|
|
|
dbConnection.setObject(certificateData, forKey: senderCertificateKey(), inCollection: kUDCollection)
|
|
|
|
dbConnection.setObject(certificateData, forKey: senderCertificateKey(), inCollection: kUDCollection)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -340,11 +379,23 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
|
|
|
return IsUsingProductionService() ? kUDCurrentSenderCertificateKey_Production : kUDCurrentSenderCertificateKey_Staging
|
|
|
|
return IsUsingProductionService() ? kUDCurrentSenderCertificateKey_Production : kUDCurrentSenderCertificateKey_Staging
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private func senderCertificateDateKey() -> String {
|
|
|
|
|
|
|
|
return IsUsingProductionService() ? kUDCurrentSenderCertificateDateKey_Production : kUDCurrentSenderCertificateDateKey_Staging
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
@objc
|
|
|
|
public func ensureSenderCertificate(success:@escaping (SMKSenderCertificate) -> Void,
|
|
|
|
public func ensureSenderCertificate(success:@escaping (SMKSenderCertificate) -> Void,
|
|
|
|
failure:@escaping (Error) -> Void) {
|
|
|
|
failure:@escaping (Error) -> Void) {
|
|
|
|
|
|
|
|
return ensureSenderCertificate(certificateExpirationPolicy: .permissive,
|
|
|
|
|
|
|
|
success: success,
|
|
|
|
|
|
|
|
failure: failure)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private func ensureSenderCertificate(certificateExpirationPolicy: OWSUDCertificateExpirationPolicy,
|
|
|
|
|
|
|
|
success:@escaping (SMKSenderCertificate) -> Void,
|
|
|
|
|
|
|
|
failure:@escaping (Error) -> Void) {
|
|
|
|
firstly {
|
|
|
|
firstly {
|
|
|
|
ensureSenderCertificate()
|
|
|
|
ensureSenderCertificate(certificateExpirationPolicy: certificateExpirationPolicy)
|
|
|
|
}.map { certificate in
|
|
|
|
}.map { certificate in
|
|
|
|
success(certificate)
|
|
|
|
success(certificate)
|
|
|
|
}.catch { error in
|
|
|
|
}.catch { error in
|
|
|
@ -352,9 +403,11 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
|
|
|
}.retainUntilComplete()
|
|
|
|
}.retainUntilComplete()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public func ensureSenderCertificate() -> Promise<SMKSenderCertificate> {
|
|
|
|
public func ensureSenderCertificate(certificateExpirationPolicy: OWSUDCertificateExpirationPolicy) -> Promise<SMKSenderCertificate> {
|
|
|
|
// If there is a valid cached sender certificate, use that.
|
|
|
|
// If there is a valid cached sender certificate, use that.
|
|
|
|
if let certificate = senderCertificate() {
|
|
|
|
//
|
|
|
|
|
|
|
|
// NOTE: We use a "strict" expiration policy.
|
|
|
|
|
|
|
|
if let certificate = senderCertificate(certificateExpirationPolicy: certificateExpirationPolicy) {
|
|
|
|
return Promise.value(certificate)
|
|
|
|
return Promise.value(certificate)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|