Update configuration message handling for ED25519 key pairs
This commit is contained in:
parent
2e75408ffa
commit
6ed7c9753a
|
@ -1,4 +1,5 @@
|
||||||
import SessionUtilitiesKit
|
import SessionUtilitiesKit
|
||||||
|
import Sodium
|
||||||
|
|
||||||
@objc(SNConfigurationMessage)
|
@objc(SNConfigurationMessage)
|
||||||
public final class ConfigurationMessage : ControlMessage {
|
public final class ConfigurationMessage : ControlMessage {
|
||||||
|
@ -98,17 +99,19 @@ extension ConfigurationMessage {
|
||||||
public final class ClosedGroup : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
|
public final class ClosedGroup : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
|
||||||
public let publicKey: String
|
public let publicKey: String
|
||||||
public let name: String
|
public let name: String
|
||||||
public let encryptionKeyPair: ECKeyPair
|
public let x25519KeyPair: ECKeyPair
|
||||||
|
public let ed25519KeyPair: Sign.KeyPair?
|
||||||
public let members: Set<String>
|
public let members: Set<String>
|
||||||
public let admins: Set<String>
|
public let admins: Set<String>
|
||||||
public let expirationTimer: UInt32
|
public let expirationTimer: UInt32
|
||||||
|
|
||||||
public var isValid: Bool { !members.isEmpty && !admins.isEmpty }
|
public var isValid: Bool { !members.isEmpty && !admins.isEmpty }
|
||||||
|
|
||||||
public init(publicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: Set<String>, admins: Set<String>, expirationTimer: UInt32) {
|
public init(publicKey: String, name: String, x25519KeyPair: ECKeyPair, ed25519KeyPair: Sign.KeyPair?, members: Set<String>, admins: Set<String>, expirationTimer: UInt32) {
|
||||||
self.publicKey = publicKey
|
self.publicKey = publicKey
|
||||||
self.name = name
|
self.name = name
|
||||||
self.encryptionKeyPair = encryptionKeyPair
|
self.x25519KeyPair = x25519KeyPair
|
||||||
|
self.ed25519KeyPair = ed25519KeyPair
|
||||||
self.members = members
|
self.members = members
|
||||||
self.admins = admins
|
self.admins = admins
|
||||||
self.expirationTimer = expirationTimer
|
self.expirationTimer = expirationTimer
|
||||||
|
@ -117,13 +120,15 @@ extension ConfigurationMessage {
|
||||||
public required init?(coder: NSCoder) {
|
public required init?(coder: NSCoder) {
|
||||||
guard let publicKey = coder.decodeObject(forKey: "publicKey") as! String?,
|
guard let publicKey = coder.decodeObject(forKey: "publicKey") as! String?,
|
||||||
let name = coder.decodeObject(forKey: "name") as! String?,
|
let name = coder.decodeObject(forKey: "name") as! String?,
|
||||||
let encryptionKeyPair = coder.decodeObject(forKey: "encryptionKeyPair") as! ECKeyPair?,
|
let x25519KeyPair = coder.decodeObject(forKey: "encryptionKeyPair") as! ECKeyPair?,
|
||||||
let members = coder.decodeObject(forKey: "members") as! Set<String>?,
|
let members = coder.decodeObject(forKey: "members") as! Set<String>?,
|
||||||
let admins = coder.decodeObject(forKey: "admins") as! Set<String>? else { return nil }
|
let admins = coder.decodeObject(forKey: "admins") as! Set<String>? else { return nil }
|
||||||
let expirationTimer = coder.decodeObject(forKey: "expirationTimer") as? UInt32 ?? 0
|
let expirationTimer = coder.decodeObject(forKey: "expirationTimer") as? UInt32 ?? 0
|
||||||
|
let ed25519KeyPair = coder.decodeObject(forKey: "ed25519KeyPair") as! Sign.KeyPair?
|
||||||
self.publicKey = publicKey
|
self.publicKey = publicKey
|
||||||
self.name = name
|
self.name = name
|
||||||
self.encryptionKeyPair = encryptionKeyPair
|
self.x25519KeyPair = x25519KeyPair
|
||||||
|
self.ed25519KeyPair = ed25519KeyPair
|
||||||
self.members = members
|
self.members = members
|
||||||
self.admins = admins
|
self.admins = admins
|
||||||
self.expirationTimer = expirationTimer
|
self.expirationTimer = expirationTimer
|
||||||
|
@ -132,7 +137,8 @@ extension ConfigurationMessage {
|
||||||
public func encode(with coder: NSCoder) {
|
public func encode(with coder: NSCoder) {
|
||||||
coder.encode(publicKey, forKey: "publicKey")
|
coder.encode(publicKey, forKey: "publicKey")
|
||||||
coder.encode(name, forKey: "name")
|
coder.encode(name, forKey: "name")
|
||||||
coder.encode(encryptionKeyPair, forKey: "encryptionKeyPair")
|
coder.encode(x25519KeyPair, forKey: "encryptionKeyPair")
|
||||||
|
coder.encode(ed25519KeyPair, forKey: "ed25519KeyPair")
|
||||||
coder.encode(members, forKey: "members")
|
coder.encode(members, forKey: "members")
|
||||||
coder.encode(admins, forKey: "admins")
|
coder.encode(admins, forKey: "admins")
|
||||||
coder.encode(expirationTimer, forKey: "expirationTimer")
|
coder.encode(expirationTimer, forKey: "expirationTimer")
|
||||||
|
@ -141,18 +147,22 @@ extension ConfigurationMessage {
|
||||||
public static func fromProto(_ proto: SNProtoConfigurationMessageClosedGroup) -> ClosedGroup? {
|
public static func fromProto(_ proto: SNProtoConfigurationMessageClosedGroup) -> ClosedGroup? {
|
||||||
guard let publicKey = proto.publicKey?.toHexString(),
|
guard let publicKey = proto.publicKey?.toHexString(),
|
||||||
let name = proto.name,
|
let name = proto.name,
|
||||||
let encryptionKeyPairAsProto = proto.x25519 else { return nil }
|
let x25519KeyPairAsProto = proto.x25519 else { return nil }
|
||||||
let encryptionKeyPair: ECKeyPair
|
let x25519KeyPair: ECKeyPair
|
||||||
do {
|
do {
|
||||||
encryptionKeyPair = try ECKeyPair(publicKeyData: encryptionKeyPairAsProto.publicKey, privateKeyData: encryptionKeyPairAsProto.privateKey)
|
x25519KeyPair = try ECKeyPair(publicKeyData: x25519KeyPairAsProto.publicKey, privateKeyData: x25519KeyPairAsProto.privateKey)
|
||||||
} catch {
|
} catch {
|
||||||
SNLog("Couldn't construct closed group from proto: \(self).")
|
SNLog("Couldn't construct closed group from proto: \(self).")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
var ed25519KeyPair: Sign.KeyPair? = nil
|
||||||
|
if let ed25519KeyPairAsProto = proto.ed25519 {
|
||||||
|
ed25519KeyPair = Sign.KeyPair(publicKey: Bytes(ed25519KeyPairAsProto.publicKey), secretKey: Bytes(ed25519KeyPairAsProto.privateKey))
|
||||||
|
}
|
||||||
let members = Set(proto.members.map { $0.toHexString() })
|
let members = Set(proto.members.map { $0.toHexString() })
|
||||||
let admins = Set(proto.admins.map { $0.toHexString() })
|
let admins = Set(proto.admins.map { $0.toHexString() })
|
||||||
let expirationTimer = proto.expirationTimer
|
let expirationTimer = proto.expirationTimer
|
||||||
let result = ClosedGroup(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins, expirationTimer: expirationTimer)
|
let result = ClosedGroup(publicKey: publicKey, name: name, x25519KeyPair: x25519KeyPair, ed25519KeyPair: ed25519KeyPair, members: members, admins: admins, expirationTimer: expirationTimer)
|
||||||
guard result.isValid else { return nil }
|
guard result.isValid else { return nil }
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -163,8 +173,8 @@ extension ConfigurationMessage {
|
||||||
result.setPublicKey(Data(hex: publicKey))
|
result.setPublicKey(Data(hex: publicKey))
|
||||||
result.setName(name)
|
result.setName(name)
|
||||||
do {
|
do {
|
||||||
let encryptionKeyPairAsProto = try SNProtoKeyPair.builder(publicKey: encryptionKeyPair.publicKey, privateKey: encryptionKeyPair.privateKey).build()
|
let x25519KeyPairAsProto = try SNProtoKeyPair.builder(publicKey: x25519KeyPair.publicKey, privateKey: x25519KeyPair.privateKey).build()
|
||||||
result.setX25519(encryptionKeyPairAsProto)
|
result.setX25519(x25519KeyPairAsProto)
|
||||||
} catch {
|
} catch {
|
||||||
SNLog("Couldn't construct closed group proto from: \(self).")
|
SNLog("Couldn't construct closed group proto from: \(self).")
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -204,7 +204,7 @@ extension MessageReceiver {
|
||||||
let allClosedGroupPublicKeys = storage.getUserClosedGroupPublicKeys()
|
let allClosedGroupPublicKeys = storage.getUserClosedGroupPublicKeys()
|
||||||
for closedGroup in message.closedGroups {
|
for closedGroup in message.closedGroups {
|
||||||
guard !allClosedGroupPublicKeys.contains(closedGroup.publicKey) else { continue }
|
guard !allClosedGroupPublicKeys.contains(closedGroup.publicKey) else { continue }
|
||||||
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, x25519KeyPair: closedGroup.encryptionKeyPair,
|
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, x25519KeyPair: closedGroup.x25519KeyPair,
|
||||||
members: [String](closedGroup.members), admins: [String](closedGroup.admins), expirationTimer: closedGroup.expirationTimer, ed25519KeyPair: nil,
|
members: [String](closedGroup.members), admins: [String](closedGroup.admins), expirationTimer: closedGroup.expirationTimer, ed25519KeyPair: nil,
|
||||||
messageSentTimestamp: message.sentTimestamp!, using: transaction)
|
messageSentTimestamp: message.sentTimestamp!, using: transaction)
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
|
||||||
// TODO: We could consider actually handling the update here. Not sure if there's enough time though, seeing as though
|
// TODO: We could consider actually handling the update here. Not sure if there's enough time though, seeing as though
|
||||||
// in some cases we need to send messages (e.g. our sender key) to a number of other users.
|
// in some cases we need to send messages (e.g. our sender key) to a number of other users.
|
||||||
switch closedGroupControlMessage.kind {
|
switch closedGroupControlMessage.kind {
|
||||||
case .new(_, let name, _, _, _, _): snippet = "\(senderDisplayName) added you to \(name)"
|
case .new(_, let name, _, _, _, _, _): snippet = "\(senderDisplayName) added you to \(name)"
|
||||||
default: return self.completeSilenty()
|
default: return self.completeSilenty()
|
||||||
}
|
}
|
||||||
default: return self.completeSilenty()
|
default: return self.completeSilenty()
|
||||||
|
|
|
@ -20,8 +20,9 @@ extension ConfigurationMessage {
|
||||||
let groupID = thread.groupModel.groupId
|
let groupID = thread.groupModel.groupId
|
||||||
let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID)
|
let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID)
|
||||||
guard storage.isClosedGroup(groupPublicKey),
|
guard storage.isClosedGroup(groupPublicKey),
|
||||||
let encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else { return }
|
let x25519KeyPair = storage.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else { return }
|
||||||
let closedGroup = ClosedGroup(publicKey: groupPublicKey, name: thread.groupModel.groupName!, encryptionKeyPair: encryptionKeyPair,
|
let ed25519KeyPair = storage.getLatestClosedGroupAuthenticationKeyPair(for: groupPublicKey)
|
||||||
|
let closedGroup = ClosedGroup(publicKey: groupPublicKey, name: thread.groupModel.groupName!, x25519KeyPair: x25519KeyPair, ed25519KeyPair: ed25519KeyPair,
|
||||||
members: Set(thread.groupModel.groupMemberIds), admins: Set(thread.groupModel.groupAdminIds), expirationTimer: thread.disappearingMessagesDuration(with: transaction))
|
members: Set(thread.groupModel.groupMemberIds), admins: Set(thread.groupModel.groupAdminIds), expirationTimer: thread.disappearingMessagesDuration(with: transaction))
|
||||||
closedGroups.insert(closedGroup)
|
closedGroups.insert(closedGroup)
|
||||||
case .openGroup:
|
case .openGroup:
|
||||||
|
|
Loading…
Reference in New Issue