mirror of https://github.com/oxen-io/session-ios
Additional encryption work on id blinding
Got the updated blinding logic working (at least when authenticating a request - still need to deal with message signing and verification) Storing the server capabilities in the database now so we can correctly blind requests based on them Renamed the remaining 'v2' functions and classes to just be 'OpenGroup' since there isn't a 'V2' anymore Cleaned up a few TODOs and functionspull/592/head
parent
b655882cbd
commit
ef09d4d5aa
@ -1,42 +1,66 @@
|
||||
import Sodium
|
||||
import SessionUtilitiesKit
|
||||
|
||||
// FIXME: We need to leave the @objc name as `SNOpenGroupV2` otherwise YapDatabase won't be able to decode it
|
||||
@objc(SNOpenGroupV2)
|
||||
public final class OpenGroupV2 : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
|
||||
public final class OpenGroup: NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
|
||||
@objc public let server: String
|
||||
@objc public let room: String
|
||||
public let id: String
|
||||
@objc public let name: String
|
||||
|
||||
@objc public let publicKey: String
|
||||
@objc public let name: String
|
||||
@objc public let groupDescription: String? // API key is 'description'
|
||||
|
||||
/// The ID with which the image can be retrieved from the server.
|
||||
public let imageID: String?
|
||||
|
||||
/// Monotonic room information counter that increases each time the room's metadata changes
|
||||
public let infoUpdates: Int64
|
||||
|
||||
public init(server: String, room: String, name: String, publicKey: String, imageID: String?) {
|
||||
public init(
|
||||
server: String,
|
||||
room: String,
|
||||
publicKey: String,
|
||||
name: String,
|
||||
groupDescription: String?,
|
||||
imageID: String?,
|
||||
infoUpdates: Int64
|
||||
) {
|
||||
self.server = server.lowercased()
|
||||
self.room = room
|
||||
self.id = "\(server).\(room)"
|
||||
self.name = name
|
||||
self.publicKey = publicKey
|
||||
self.name = name
|
||||
self.groupDescription = groupDescription
|
||||
self.imageID = imageID
|
||||
self.infoUpdates = infoUpdates
|
||||
}
|
||||
|
||||
// MARK: Coding
|
||||
// MARK: - Coding
|
||||
|
||||
public init?(coder: NSCoder) {
|
||||
server = coder.decodeObject(forKey: "server") as! String
|
||||
room = coder.decodeObject(forKey: "room") as! String
|
||||
self.id = "\(server).\(room)"
|
||||
name = coder.decodeObject(forKey: "name") as! String
|
||||
|
||||
publicKey = coder.decodeObject(forKey: "publicKey") as! String
|
||||
name = coder.decodeObject(forKey: "name") as! String
|
||||
groupDescription = coder.decodeObject(forKey: "groupDescription") as? String
|
||||
imageID = coder.decodeObject(forKey: "imageID") as! String?
|
||||
infoUpdates = ((coder.decodeObject(forKey: "infoUpdates") as? Int64) ?? 0)
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
public func encode(with coder: NSCoder) {
|
||||
coder.encode(server, forKey: "server")
|
||||
coder.encode(room, forKey: "room")
|
||||
coder.encode(name, forKey: "name")
|
||||
coder.encode(publicKey, forKey: "publicKey")
|
||||
coder.encode(name, forKey: "name")
|
||||
if let groupDescription = groupDescription { coder.encode(groupDescription, forKey: "groupDescription") }
|
||||
if let imageID = imageID { coder.encode(imageID, forKey: "imageID") }
|
||||
coder.encode(infoUpdates, forKey: "infoUpdates")
|
||||
}
|
||||
|
||||
override public var description: String { "\(name) (Server: \(server), Room: \(room)" }
|
||||
@ -0,0 +1,46 @@
|
||||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import Sodium
|
||||
import SessionUtilitiesKit
|
||||
|
||||
extension OpenGroupAPI {
|
||||
@objc(SOGSServer)
|
||||
public final class Server: NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
|
||||
@objc public let name: String
|
||||
public let capabilities: Capabilities
|
||||
|
||||
public init(
|
||||
name: String,
|
||||
capabilities: Capabilities
|
||||
) {
|
||||
self.name = name.lowercased()
|
||||
self.capabilities = capabilities
|
||||
}
|
||||
|
||||
// MARK: - Coding
|
||||
|
||||
public init?(coder: NSCoder) {
|
||||
let capabilitiesString: [String] = coder.decodeObject(forKey: "capabilities") as! [String]
|
||||
let missingCapabilitiesString: [String]? = coder.decodeObject(forKey: "missingCapabilities") as? [String]
|
||||
|
||||
name = coder.decodeObject(forKey: "name") as! String
|
||||
capabilities = Capabilities(
|
||||
capabilities: capabilitiesString.map { Capabilities.Capability(from: $0) },
|
||||
missing: missingCapabilitiesString?.map { Capabilities.Capability(from: $0) }
|
||||
)
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
public func encode(with coder: NSCoder) {
|
||||
coder.encode(name, forKey: "name")
|
||||
coder.encode(capabilities.capabilities.map { $0.rawValue }, forKey: "capabilities")
|
||||
coder.encode(capabilities.missing?.map { $0.rawValue }, forKey: "missingCapabilities")
|
||||
}
|
||||
|
||||
override public var description: String {
|
||||
"\(name) (Capabilities: [\(capabilities.capabilities.map { $0.rawValue }.joined(separator: ", "))], Missing: [\((capabilities.missing ?? []).map { $0.rawValue }.joined(separator: ", "))])"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,24 @@
|
||||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import Sodium
|
||||
import Curve25519Kit
|
||||
|
||||
/// The `BlindedECKeyPair` is essentially the same as the `ECKeyPair` except it allows us to more easily distinguish between the two,
|
||||
/// additionally when generating the `hexEncodedPublicKey` value it will apply the correct prefix
|
||||
public class BlindedECKeyPair: ECKeyPair {}
|
||||
|
||||
public enum IdPrefix: String, CaseIterable {
|
||||
case standard = "05" // Used for identified users, open groups, etc.
|
||||
case blinded = "15" // Used for participants in open groups
|
||||
case blinded = "15" // Used for participants in open groups with blinding enabled
|
||||
case unblinded = "00" // Used for participants in open groups with blinding disabled
|
||||
|
||||
public init?(with sessionId: String) {
|
||||
// TODO: Determine if we want this 'idPrefix' method (would need to validate both `ECKeyPair` and `Box.KeyPair` types)
|
||||
guard ECKeyPair.isValidHexEncodedPublicKey(candidate: sessionId) else { return nil }
|
||||
guard let targetPrefix: IdPrefix = IdPrefix(rawValue: String(sessionId.prefix(2))) else { return nil }
|
||||
|
||||
self = targetPrefix
|
||||
}
|
||||
|
||||
public func hexEncodedPublicKey(for publicKey: Bytes) -> String {
|
||||
|
||||
return self.rawValue + publicKey.map { String(format: "%02hhx", $0) }.joined()
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue