Partially resolve TODOs

pull/218/head
nielsandriesse 5 years ago
parent 41aa825e5d
commit c5a535685a

@ -248,11 +248,18 @@ message DataMessage {
CHAIN_KEY = 2; // groupPublicKey, chainKeys
}
message SenderKey {
// @required
optional bytes chainKey = 1;
// @required
optional uint32 keyIndex = 2;
}
optional string name = 1;
// @required
optional bytes groupPublicKey = 2;
optional bytes groupPrivateKey = 3;
repeated bytes chainKeys = 4;
repeated SenderKey senderKeys = 4;
repeated string members = 5;
repeated string admins = 6;
// @required

@ -9,11 +9,21 @@ internal final class ClosedGroupUpdateMessage : TSOutgoingMessage {
@objc internal override func shouldBeSaved() -> Bool { return false }
@objc internal override func shouldSyncTranscript() -> Bool { return false }
// MARK: Sender Key
internal struct SenderKey {
internal let chainKey: Data
internal let keyIndex: UInt
internal func toProto() throws -> SSKProtoDataMessageClosedGroupUpdateSenderKey {
return try SSKProtoDataMessageClosedGroupUpdateSenderKey.builder(chainKey: chainKey, keyIndex: UInt32(keyIndex)).build()
}
}
// MARK: Kind
internal enum Kind {
case new(groupPublicKey: Data, name: String, groupPrivateKey: Data, chainKeys: [Data], members: [String], admins: [String])
case info(groupPublicKey: Data, name: String, chainKeys: [Data], members: [String], admins: [String])
case chainKey(groupPublicKey: Data, chainKey: Data)
case new(groupPublicKey: Data, name: String, groupPrivateKey: Data, senderKeys: [SenderKey], members: [String], admins: [String])
case info(groupPublicKey: Data, name: String, senderKeys: [SenderKey], members: [String], admins: [String])
case chainKey(groupPublicKey: Data, senderKey: SenderKey)
}
// MARK: Initialization
@ -38,22 +48,22 @@ internal final class ClosedGroupUpdateMessage : TSOutgoingMessage {
do {
let closedGroupUpdate: SSKProtoDataMessageClosedGroupUpdate.SSKProtoDataMessageClosedGroupUpdateBuilder
switch kind {
case .new(let groupPublicKey, let name, let groupPrivateKey, let chainKeys, let members, let admins):
case .new(let groupPublicKey, let name, let groupPrivateKey, let senderKeys, let members, let admins):
closedGroupUpdate = SSKProtoDataMessageClosedGroupUpdate.builder(groupPublicKey: groupPublicKey, type: .new)
closedGroupUpdate.setName(name)
closedGroupUpdate.setGroupPrivateKey(groupPrivateKey)
closedGroupUpdate.setChainKeys(chainKeys)
closedGroupUpdate.setSenderKeys(try senderKeys.map { try $0.toProto() })
closedGroupUpdate.setMembers(members)
closedGroupUpdate.setAdmins(admins)
case .info(let groupPublicKey, let name, let chainKeys, let members, let admins):
case .info(let groupPublicKey, let name, let senderKeys, let members, let admins):
closedGroupUpdate = SSKProtoDataMessageClosedGroupUpdate.builder(groupPublicKey: groupPublicKey, type: .info)
closedGroupUpdate.setName(name)
closedGroupUpdate.setChainKeys(chainKeys)
closedGroupUpdate.setSenderKeys(try senderKeys.map { try $0.toProto() })
closedGroupUpdate.setMembers(members)
closedGroupUpdate.setAdmins(admins)
case .chainKey(let groupPublicKey, let chainKey):
case .chainKey(let groupPublicKey, let senderKey):
closedGroupUpdate = SSKProtoDataMessageClosedGroupUpdate.builder(groupPublicKey: groupPublicKey, type: .chainKey)
closedGroupUpdate.setChainKeys([ chainKey ])
closedGroupUpdate.setSenderKeys([ try senderKey.toProto() ])
}
builder.setClosedGroupUpdate(try closedGroupUpdate.build())
} catch {

@ -15,9 +15,8 @@ public final class ClosedGroupsProtocol : NSObject {
// TODO:
// Always reset all ratchets if someone leaves or is kicked?
// Validate that update messages come from admins
// Closed group update message deserialization
// Include key indexes
// Group model saving
// Multi device
// ClosedGroupsProtocol
// SyncMessagesProtocol
@ -50,11 +49,11 @@ public final class ClosedGroupsProtocol : NSObject {
// the user can only pick from existing contacts)
establishSessionsIfNeeded(with: members, using: transaction)
// Send a closed group update message to all members involved using established channels
let chainKeys = ratchets.map { Data(hex: $0.chainKey) }
let senderKeys = ratchets.map { ClosedGroupUpdateMessage.SenderKey(chainKey: Data(hex: $0.chainKey), keyIndex: $0.keyIndex) }
for member in members {
let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction)
thread.save(with: transaction)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.new(groupPublicKey: Data(hex: groupPublicKey), name: name, groupPrivateKey: groupKeyPair.privateKey, chainKeys: chainKeys, members: members, admins: admins)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.new(groupPublicKey: Data(hex: groupPublicKey), name: name, groupPrivateKey: groupKeyPair.privateKey, senderKeys: senderKeys, members: members, admins: admins)
let closedGroupUpdateMessage = ClosedGroupUpdateMessage(thread: thread, kind: closedGroupUpdateMessageKind)
let messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue
messageSenderJobQueue.add(message: closedGroupUpdateMessage, transaction: transaction)
@ -91,14 +90,16 @@ public final class ClosedGroupsProtocol : NSObject {
}
// Send a closed group update message to the existing members with the new members' ratchets (this message is
// aimed at the group)
let chainKeys = ratchets.map { Data(hex: $0.chainKey) }
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, chainKeys: chainKeys, members: members, admins: admins)
let senderKeys = ratchets.map { ClosedGroupUpdateMessage.SenderKey(chainKey: Data(hex: $0.chainKey), keyIndex: $0.keyIndex) }
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, senderKeys: senderKeys, members: members, admins: admins)
let closedGroupUpdateMessage = ClosedGroupUpdateMessage(thread: thread, kind: closedGroupUpdateMessageKind)
messageSenderJobQueue.add(message: closedGroupUpdateMessage, transaction: transaction)
// Send closed group update messages to the new members using established channels
let allChainKeys = Storage.getAllClosedGroupRatchets(for: groupPublicKey).map { Data(hex: $0.chainKey) } // TODO: We need to include the key index here as well
let allSenderKeys = Storage.getAllClosedGroupRatchets(for: groupPublicKey).map {
ClosedGroupUpdateMessage.SenderKey(chainKey: Data(hex: $0.chainKey), keyIndex: $0.keyIndex)
}
for member in newMembers {
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, chainKeys: allChainKeys, members: members, admins: admins)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, senderKeys: allSenderKeys, members: members, admins: admins)
let thread = TSContactThread.getOrCreateThread(contactId: member)
thread.save(with: transaction)
let closedGroupUpdateMessage = ClosedGroupUpdateMessage(thread: thread, kind: closedGroupUpdateMessageKind)
@ -130,7 +131,7 @@ public final class ClosedGroupsProtocol : NSObject {
// sessions would've already been established previously)
establishSessionsIfNeeded(with: group.groupMemberIds, using: transaction) // Intentionally not `members`
// Send a closed group update message to the removed members (this message is aimed at the group)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, chainKeys: [], members: members, admins: admins)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, senderKeys: [], members: members, admins: admins)
let closedGroupUpdateMessage = ClosedGroupUpdateMessage(thread: thread, kind: closedGroupUpdateMessageKind)
messageSenderJobQueue.add(message: closedGroupUpdateMessage, transaction: transaction)
// Generate new ratchets for everyone except the members that were removed (it's important that
@ -140,11 +141,11 @@ public final class ClosedGroupsProtocol : NSObject {
}
// Send a closed group update message to all members (minus the ones that were removed) with everyone's new
// ratchets using established channels
let chainKeys = ratchets.map { Data(hex: $0.chainKey) }
let senderKeys = ratchets.map { ClosedGroupUpdateMessage.SenderKey(chainKey: Data(hex: $0.chainKey), keyIndex: $0.keyIndex) }
for member in members {
let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction)
thread.save(with: transaction)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, chainKeys: chainKeys, members: members, admins: admins)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, senderKeys: senderKeys, members: members, admins: admins)
let closedGroupUpdateMessage = ClosedGroupUpdateMessage(thread: thread, kind: closedGroupUpdateMessageKind)
messageSenderJobQueue.add(message: closedGroupUpdateMessage, transaction: transaction)
}
@ -170,7 +171,7 @@ public final class ClosedGroupsProtocol : NSObject {
members.remove(at: indexOfUser)
// Send the update to the group (don't include new ratchets as everyone should generate new ratchets
// individually in this case)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, chainKeys: [], members: members, admins: admins)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, senderKeys: [], members: members, admins: admins)
let closedGroupUpdateMessage = ClosedGroupUpdateMessage(thread: thread, kind: closedGroupUpdateMessageKind)
let messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue
messageSenderJobQueue.add(message: closedGroupUpdateMessage, transaction: transaction)
@ -187,7 +188,7 @@ public final class ClosedGroupsProtocol : NSObject {
guard let closedGroupUpdate = dataMessage.closedGroupUpdate else { return }
switch closedGroupUpdate.type {
case .new: handleNewGroupMessage(closedGroupUpdate, using: transaction)
case .info: handleInfoMessage(closedGroupUpdate, using: transaction)
case .info: handleInfoMessage(closedGroupUpdate, from: publicKey, using: transaction)
case .chainKey: handleChainKeyMessage(closedGroupUpdate, from: publicKey, using: transaction)
}
}
@ -197,12 +198,12 @@ public final class ClosedGroupsProtocol : NSObject {
let groupPublicKey = closedGroupUpdate.groupPublicKey.toHexString()
let name = closedGroupUpdate.name
let groupPrivateKey = closedGroupUpdate.groupPrivateKey!
let chainKeys = closedGroupUpdate.chainKeys
let senderKeys = closedGroupUpdate.senderKeys
let members = closedGroupUpdate.members
let admins = closedGroupUpdate.admins
// Persist the ratchets
zip(members, chainKeys).forEach { (member, chainKey) in
let ratchet = ClosedGroupRatchet(chainKey: chainKey.toHexString(), keyIndex: 0, messageKeys: [])
zip(members, senderKeys).forEach { (member, senderKey) in
let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: [])
Storage.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: member, ratchet: ratchet, using: transaction)
}
// Create the group
@ -223,12 +224,11 @@ public final class ClosedGroupsProtocol : NSObject {
/// Invoked upon receiving a group update. A group update is sent out when a group's name is changed, when new users
/// are added, when users leave or are kicked, or if the group admins are changed.
private static func handleInfoMessage(_ closedGroupUpdate: SSKProtoDataMessageClosedGroupUpdate, using transaction: YapDatabaseReadWriteTransaction) {
// TODO: Check that the sender was an admin
private static func handleInfoMessage(_ closedGroupUpdate: SSKProtoDataMessageClosedGroupUpdate, from senderPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) {
// Unwrap the message
let groupPublicKey = closedGroupUpdate.groupPublicKey.toHexString()
let name = closedGroupUpdate.name
let chainKeys = closedGroupUpdate.chainKeys
let senderKeys = closedGroupUpdate.senderKeys
let members = closedGroupUpdate.members
let admins = closedGroupUpdate.admins
// Get the group
@ -237,15 +237,23 @@ public final class ClosedGroupsProtocol : NSObject {
return print("[Loki] Ignoring closed group update for nonexistent group.")
}
let group = thread.groupModel
// Check that the sender is an admin (before the update)
var isSenderAdmin = false
Storage.read { transaction in
isSenderAdmin = !thread.isUserAdmin(inGroup: senderPublicKey, transaction: transaction) // TODO: Validate that `senderPublicKey` here isn't the group public key
}
guard isSenderAdmin else {
return print("[Loki] Ignoring closed group update from non-admin.")
}
// Establish sessions if needed (it's important that this happens before the code below)
establishSessionsIfNeeded(with: members, using: transaction)
// Parse out any new members and store their ratchets (it's important that
// this happens before handling removed members)
let oldMembers = group.groupMemberIds
let newMembers = members.filter { !oldMembers.contains($0) }
if newMembers.count == chainKeys.count { // If someone left or was kicked the message won't have any chain keys
zip(newMembers, chainKeys).forEach { (member, chainKey) in
let ratchet = ClosedGroupRatchet(chainKey: chainKey.toHexString(), keyIndex: 0, messageKeys: [])
if newMembers.count == senderKeys.count { // If someone left or was kicked the message won't have any sender keys
zip(newMembers, senderKeys).forEach { (member, senderKey) in
let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: [])
Storage.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: member, ratchet: ratchet, using: transaction)
}
}
@ -255,11 +263,12 @@ public final class ClosedGroupsProtocol : NSObject {
Storage.removeAllClosedGroupRatchets(for: groupPublicKey, using: transaction)
let userPublicKey = getUserHexEncodedPublicKey()
let newRatchet = SharedSenderKeysImplementation.shared.generateRatchet(for: groupPublicKey, senderPublicKey: userPublicKey, using: transaction)
let newSenderKey = ClosedGroupUpdateMessage.SenderKey(chainKey: Data(hex: newRatchet.chainKey), keyIndex: newRatchet.keyIndex)
Storage.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: userPublicKey, ratchet: newRatchet, using: transaction)
for member in members {
let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction)
thread.save(with: transaction)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.chainKey(groupPublicKey: Data(hex: groupPublicKey), chainKey: Data(hex: newRatchet.chainKey))
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.chainKey(groupPublicKey: Data(hex: groupPublicKey), senderKey: newSenderKey)
let closedGroupUpdateMessage = ClosedGroupUpdateMessage(thread: thread, kind: closedGroupUpdateMessageKind)
let messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue
messageSenderJobQueue.add(message: closedGroupUpdateMessage, transaction: transaction)
@ -277,10 +286,10 @@ public final class ClosedGroupsProtocol : NSObject {
/// Invoked upon receiving a chain key from another user.
private static func handleChainKeyMessage(_ closedGroupUpdate: SSKProtoDataMessageClosedGroupUpdate, from senderPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) {
let groupPublicKey = closedGroupUpdate.groupPublicKey.toHexString()
guard let chainKey = closedGroupUpdate.chainKeys.first else {
guard let senderKey = closedGroupUpdate.senderKeys.first else {
return print("[Loki] Ignoring invalid closed group update.")
}
let ratchet = ClosedGroupRatchet(chainKey: chainKey.toHexString(), keyIndex: 0, messageKeys: [])
let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: [])
Storage.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: senderPublicKey, ratchet: ratchet, using: transaction)
}

@ -3287,6 +3287,118 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
#endif
// MARK: - SSKProtoDataMessageClosedGroupUpdateSenderKey
@objc public class SSKProtoDataMessageClosedGroupUpdateSenderKey: NSObject {
// MARK: - SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder
@objc public class func builder(chainKey: Data, keyIndex: UInt32) -> SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder {
return SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder(chainKey: chainKey, keyIndex: keyIndex)
}
// asBuilder() constructs a builder that reflects the proto's contents.
@objc public func asBuilder() -> SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder {
let builder = SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder(chainKey: chainKey, keyIndex: keyIndex)
return builder
}
@objc public class SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder: NSObject {
private var proto = SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey()
@objc fileprivate override init() {}
@objc fileprivate init(chainKey: Data, keyIndex: UInt32) {
super.init()
setChainKey(chainKey)
setKeyIndex(keyIndex)
}
@objc public func setChainKey(_ valueParam: Data) {
proto.chainKey = valueParam
}
@objc public func setKeyIndex(_ valueParam: UInt32) {
proto.keyIndex = valueParam
}
@objc public func build() throws -> SSKProtoDataMessageClosedGroupUpdateSenderKey {
return try SSKProtoDataMessageClosedGroupUpdateSenderKey.parseProto(proto)
}
@objc public func buildSerializedData() throws -> Data {
return try SSKProtoDataMessageClosedGroupUpdateSenderKey.parseProto(proto).serializedData()
}
}
fileprivate let proto: SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey
@objc public let chainKey: Data
@objc public let keyIndex: UInt32
private init(proto: SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey,
chainKey: Data,
keyIndex: UInt32) {
self.proto = proto
self.chainKey = chainKey
self.keyIndex = keyIndex
}
@objc
public func serializedData() throws -> Data {
return try self.proto.serializedData()
}
@objc public class func parseData(_ serializedData: Data) throws -> SSKProtoDataMessageClosedGroupUpdateSenderKey {
let proto = try SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey(serializedData: serializedData)
return try parseProto(proto)
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey) throws -> SSKProtoDataMessageClosedGroupUpdateSenderKey {
guard proto.hasChainKey else {
throw SSKProtoError.invalidProtobuf(description: "\(logTag) missing required field: chainKey")
}
let chainKey = proto.chainKey
guard proto.hasKeyIndex else {
throw SSKProtoError.invalidProtobuf(description: "\(logTag) missing required field: keyIndex")
}
let keyIndex = proto.keyIndex
// MARK: - Begin Validation Logic for SSKProtoDataMessageClosedGroupUpdateSenderKey -
// MARK: - End Validation Logic for SSKProtoDataMessageClosedGroupUpdateSenderKey -
let result = SSKProtoDataMessageClosedGroupUpdateSenderKey(proto: proto,
chainKey: chainKey,
keyIndex: keyIndex)
return result
}
@objc public override var debugDescription: String {
return "\(proto)"
}
}
#if DEBUG
extension SSKProtoDataMessageClosedGroupUpdateSenderKey {
@objc public func serializedDataIgnoringErrors() -> Data? {
return try! self.serializedData()
}
}
extension SSKProtoDataMessageClosedGroupUpdateSenderKey.SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder {
@objc public func buildIgnoringErrors() -> SSKProtoDataMessageClosedGroupUpdateSenderKey? {
return try! self.build()
}
}
#endif
// MARK: - SSKProtoDataMessageClosedGroupUpdate
@objc public class SSKProtoDataMessageClosedGroupUpdate: NSObject {
@ -3330,7 +3442,7 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
if let _value = groupPrivateKey {
builder.setGroupPrivateKey(_value)
}
builder.setChainKeys(chainKeys)
builder.setSenderKeys(senderKeys)
builder.setMembers(members)
builder.setAdmins(admins)
return builder
@ -3361,14 +3473,14 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
proto.groupPrivateKey = valueParam
}
@objc public func addChainKeys(_ valueParam: Data) {
var items = proto.chainKeys
items.append(valueParam)
proto.chainKeys = items
@objc public func addSenderKeys(_ valueParam: SSKProtoDataMessageClosedGroupUpdateSenderKey) {
var items = proto.senderKeys
items.append(valueParam.proto)
proto.senderKeys = items
}
@objc public func setChainKeys(_ wrappedItems: [Data]) {
proto.chainKeys = wrappedItems
@objc public func setSenderKeys(_ wrappedItems: [SSKProtoDataMessageClosedGroupUpdateSenderKey]) {
proto.senderKeys = wrappedItems.map { $0.proto }
}
@objc public func addMembers(_ valueParam: String) {
@ -3408,6 +3520,8 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
@objc public let groupPublicKey: Data
@objc public let senderKeys: [SSKProtoDataMessageClosedGroupUpdateSenderKey]
@objc public let type: SSKProtoDataMessageClosedGroupUpdateType
@objc public var name: String? {
@ -3430,10 +3544,6 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
return proto.hasGroupPrivateKey
}
@objc public var chainKeys: [Data] {
return proto.chainKeys
}
@objc public var members: [String] {
return proto.members
}
@ -3444,9 +3554,11 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
private init(proto: SignalServiceProtos_DataMessage.ClosedGroupUpdate,
groupPublicKey: Data,
senderKeys: [SSKProtoDataMessageClosedGroupUpdateSenderKey],
type: SSKProtoDataMessageClosedGroupUpdateType) {
self.proto = proto
self.groupPublicKey = groupPublicKey
self.senderKeys = senderKeys
self.type = type
}
@ -3466,6 +3578,9 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
}
let groupPublicKey = proto.groupPublicKey
var senderKeys: [SSKProtoDataMessageClosedGroupUpdateSenderKey] = []
senderKeys = try proto.senderKeys.map { try SSKProtoDataMessageClosedGroupUpdateSenderKey.parseProto($0) }
guard proto.hasType else {
throw SSKProtoError.invalidProtobuf(description: "\(logTag) missing required field: type")
}
@ -3477,6 +3592,7 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
let result = SSKProtoDataMessageClosedGroupUpdate(proto: proto,
groupPublicKey: groupPublicKey,
senderKeys: senderKeys,
type: type)
return result
}

@ -1525,7 +1525,7 @@ struct SignalServiceProtos_DataMessage {
/// Clears the value of `groupPrivateKey`. Subsequent reads from it will return its default value.
mutating func clearGroupPrivateKey() {self._groupPrivateKey = nil}
var chainKeys: [Data] = []
var senderKeys: [SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey] = []
var members: [String] = []
@ -1578,6 +1578,39 @@ struct SignalServiceProtos_DataMessage {
}
struct SenderKey {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// @required
var chainKey: Data {
get {return _chainKey ?? SwiftProtobuf.Internal.emptyData}
set {_chainKey = newValue}
}
/// Returns true if `chainKey` has been explicitly set.
var hasChainKey: Bool {return self._chainKey != nil}
/// Clears the value of `chainKey`. Subsequent reads from it will return its default value.
mutating func clearChainKey() {self._chainKey = nil}
/// @required
var keyIndex: UInt32 {
get {return _keyIndex ?? 0}
set {_keyIndex = newValue}
}
/// Returns true if `keyIndex` has been explicitly set.
var hasKeyIndex: Bool {return self._keyIndex != nil}
/// Clears the value of `keyIndex`. Subsequent reads from it will return its default value.
mutating func clearKeyIndex() {self._keyIndex = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
fileprivate var _chainKey: Data? = nil
fileprivate var _keyIndex: UInt32? = nil
}
init() {}
fileprivate var _name: String? = nil
@ -3987,7 +4020,7 @@ extension SignalServiceProtos_DataMessage.ClosedGroupUpdate: SwiftProtobuf.Messa
1: .same(proto: "name"),
2: .same(proto: "groupPublicKey"),
3: .same(proto: "groupPrivateKey"),
4: .same(proto: "chainKeys"),
4: .same(proto: "senderKeys"),
5: .same(proto: "members"),
6: .same(proto: "admins"),
7: .same(proto: "type"),
@ -3999,7 +4032,7 @@ extension SignalServiceProtos_DataMessage.ClosedGroupUpdate: SwiftProtobuf.Messa
case 1: try decoder.decodeSingularStringField(value: &self._name)
case 2: try decoder.decodeSingularBytesField(value: &self._groupPublicKey)
case 3: try decoder.decodeSingularBytesField(value: &self._groupPrivateKey)
case 4: try decoder.decodeRepeatedBytesField(value: &self.chainKeys)
case 4: try decoder.decodeRepeatedMessageField(value: &self.senderKeys)
case 5: try decoder.decodeRepeatedStringField(value: &self.members)
case 6: try decoder.decodeRepeatedStringField(value: &self.admins)
case 7: try decoder.decodeSingularEnumField(value: &self._type)
@ -4018,8 +4051,8 @@ extension SignalServiceProtos_DataMessage.ClosedGroupUpdate: SwiftProtobuf.Messa
if let v = self._groupPrivateKey {
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
}
if !self.chainKeys.isEmpty {
try visitor.visitRepeatedBytesField(value: self.chainKeys, fieldNumber: 4)
if !self.senderKeys.isEmpty {
try visitor.visitRepeatedMessageField(value: self.senderKeys, fieldNumber: 4)
}
if !self.members.isEmpty {
try visitor.visitRepeatedStringField(value: self.members, fieldNumber: 5)
@ -4037,7 +4070,7 @@ extension SignalServiceProtos_DataMessage.ClosedGroupUpdate: SwiftProtobuf.Messa
if lhs._name != rhs._name {return false}
if lhs._groupPublicKey != rhs._groupPublicKey {return false}
if lhs._groupPrivateKey != rhs._groupPrivateKey {return false}
if lhs.chainKeys != rhs.chainKeys {return false}
if lhs.senderKeys != rhs.senderKeys {return false}
if lhs.members != rhs.members {return false}
if lhs.admins != rhs.admins {return false}
if lhs._type != rhs._type {return false}
@ -4054,6 +4087,41 @@ extension SignalServiceProtos_DataMessage.ClosedGroupUpdate.TypeEnum: SwiftProto
]
}
extension SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = SignalServiceProtos_DataMessage.ClosedGroupUpdate.protoMessageName + ".SenderKey"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "chainKey"),
2: .same(proto: "keyIndex"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularBytesField(value: &self._chainKey)
case 2: try decoder.decodeSingularUInt32Field(value: &self._keyIndex)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if let v = self._chainKey {
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
}
if let v = self._keyIndex {
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey, rhs: SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey) -> Bool {
if lhs._chainKey != rhs._chainKey {return false}
if lhs._keyIndex != rhs._keyIndex {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension SignalServiceProtos_NullMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".NullMessage"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [

Loading…
Cancel
Save