Store the ED25519 key pair upon receiving it

authentication
Niels Andriesse 4 years ago
parent f6ecd9decf
commit 024eb00169

@ -1,14 +1,12 @@
import Sodium
extension Storage {
// MARK: Encryption Key Pairs
private static func getClosedGroupEncryptionKeyPairCollection(for groupPublicKey: String) -> String {
return "SNClosedGroupEncryptionKeyPairCollection-\(groupPublicKey)"
}
private static let closedGroupPublicKeyCollection = "SNClosedGroupPublicKeyCollection"
private static let closedGroupFormationTimestampCollection = "SNClosedGroupFormationTimestampCollection"
private static let closedGroupZombieMembersCollection = "SNClosedGroupZombieMembersCollection"
public func getClosedGroupEncryptionKeyPairs(for groupPublicKey: String) -> [ECKeyPair] {
let collection = Storage.getClosedGroupEncryptionKeyPairCollection(for: groupPublicKey)
var timestampsAndKeyPairs: [(timestamp: Double, keyPair: ECKeyPair)] = []
@ -25,10 +23,11 @@ extension Storage {
return getClosedGroupEncryptionKeyPairs(for: groupPublicKey).last
}
public func addClosedGroupEncryptionKeyPair(_ keyPair: ECKeyPair, for groupPublicKey: String, using transaction: Any) {
public func addClosedGroupEncryptionKeyPair(_ keyPair: ECKeyPair, for groupPublicKey: String, using transaction: Any) -> String {
let collection = Storage.getClosedGroupEncryptionKeyPairCollection(for: groupPublicKey)
let timestamp = String(Date().timeIntervalSince1970)
(transaction as! YapDatabaseReadWriteTransaction).setObject(keyPair, forKey: timestamp, inCollection: collection)
return timestamp
}
public func removeAllClosedGroupEncryptionKeyPairs(for groupPublicKey: String, using transaction: Any) {
@ -36,6 +35,19 @@ extension Storage {
(transaction as! YapDatabaseReadWriteTransaction).removeAllObjects(inCollection: collection)
}
// MARK: Authentication Key Pairs
private static func getClosedGroupAuthenticationKeyPairCollection(for groupPublicKey: String) -> String {
return "SNClosedGroupAuthenticationKeyPairCollection-\(groupPublicKey)"
}
public func addClosedGroupAuthenticationKeyPair(_ keyPair: Sign.KeyPair, for groupPublicKey: String, timestamp: String, using transaction: Any) {
let collection = Storage.getClosedGroupAuthenticationKeyPairCollection(for: groupPublicKey)
(transaction as! YapDatabaseReadWriteTransaction).setObject(keyPair, forKey: timestamp, inCollection: collection)
}
// MARK: Public Keys
private static let closedGroupPublicKeyCollection = "SNClosedGroupPublicKeyCollection"
public func getUserClosedGroupPublicKeys() -> Set<String> {
var result: Set<String> = []
Storage.read { transaction in
@ -52,6 +64,9 @@ extension Storage {
(transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: groupPublicKey, inCollection: Storage.closedGroupPublicKeyCollection)
}
// MARK: Formation Timestamps
private static let closedGroupFormationTimestampCollection = "SNClosedGroupFormationTimestampCollection"
public func getClosedGroupFormationTimestamp(for groupPublicKey: String) -> UInt64? {
var result: UInt64?
Storage.read { transaction in
@ -64,6 +79,9 @@ extension Storage {
(transaction as! YapDatabaseReadWriteTransaction).setObject(timestamp, forKey: groupPublicKey, inCollection: Storage.closedGroupFormationTimestampCollection)
}
// MARK: Zombie Members
private static let closedGroupZombieMembersCollection = "SNClosedGroupZombieMembersCollection"
public func getZombieMembers(for groupPublicKey: String) -> Set<String> {
var result: Set<String> = []
Storage.read { transaction in
@ -77,7 +95,8 @@ extension Storage {
public func setZombieMembers(for groupPublicKey: String, to zombies: Set<String>, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).setObject(zombies, forKey: groupPublicKey, inCollection: Storage.closedGroupZombieMembersCollection)
}
// MARK: Convenience
public func isClosedGroup(_ publicKey: String) -> Bool {
getUserClosedGroupPublicKeys().contains(publicKey)
}

@ -1,4 +1,5 @@
import SignalCoreKit
import Sodium
extension MessageReceiver {
@ -423,32 +424,61 @@ extension MessageReceiver {
}
// Find our wrapper and decrypt it if possible
guard let wrapper = wrappers.first(where: { $0.publicKey == userPublicKey }), let encryptedX25519KeyPair = wrapper.encryptedX25519KeyPair else { return }
// Handle the X25519 key pair
let timestamp = handleEncryptedX25519KeyPair(encryptedX25519KeyPair, for: groupPublicKey, userKeyPair: userKeyPair, transaction: transaction)
// Handle the ED25519 key pair if needed
if let timestamp = timestamp, let encryptedED25519KeyPair = wrapper.encryptedED25519KeyPair {
handleEncryptedED25519KeyPair(encryptedED25519KeyPair, for: groupPublicKey, timestamp: timestamp, userKeyPair: userKeyPair, transaction: transaction)
}
}
private static func handleEncryptedX25519KeyPair(_ encryptedX25519KeyPair: Data, for groupPublicKey: String, userKeyPair: ECKeyPair, transaction: Any) -> String? {
let plaintext: Data
do {
plaintext = try MessageReceiver.decryptWithSessionProtocol(ciphertext: encryptedX25519KeyPair, using: userKeyPair).plaintext
} catch {
return SNLog("Couldn't decrypt closed group encryption key pair.")
SNLog("Couldn't decrypt closed group encryption key pair."); return nil
}
// Parse it
let proto: SNProtoKeyPair
do {
proto = try SNProtoKeyPair.parseData(plaintext)
} catch {
return SNLog("Couldn't parse closed group encryption key pair.")
SNLog("Couldn't parse closed group encryption key pair."); return nil
}
let keyPair: ECKeyPair
do {
keyPair = try ECKeyPair(publicKeyData: proto.publicKey.removing05PrefixIfNeeded(), privateKeyData: proto.privateKey)
} catch {
return SNLog("Couldn't parse closed group encryption key pair.")
SNLog("Couldn't parse closed group encryption key pair."); return nil
}
// Store it if needed
let closedGroupEncryptionKeyPairs = Storage.shared.getClosedGroupEncryptionKeyPairs(for: groupPublicKey)
guard !closedGroupEncryptionKeyPairs.contains(keyPair) else {
return SNLog("Ignoring duplicate closed group encryption key pair.")
SNLog("Ignoring duplicate closed group encryption key pair."); return nil
}
Storage.shared.addClosedGroupEncryptionKeyPair(keyPair, for: groupPublicKey, using: transaction)
SNLog("Received a new closed group encryption key pair.")
return Storage.shared.addClosedGroupEncryptionKeyPair(keyPair, for: groupPublicKey, using: transaction)
}
private static func handleEncryptedED25519KeyPair(_ encryptedED25519KeyPair: Data, for groupPublicKey: String, timestamp: String, userKeyPair: ECKeyPair, transaction: Any) {
let plaintext: Data
do {
plaintext = try MessageReceiver.decryptWithSessionProtocol(ciphertext: encryptedED25519KeyPair, using: userKeyPair).plaintext
} catch {
return SNLog("Couldn't decrypt closed group authentication key pair.")
}
// Parse it
let proto: SNProtoKeyPair
do {
proto = try SNProtoKeyPair.parseData(plaintext)
} catch {
return SNLog("Couldn't parse closed group authentication key pair.")
}
let keyPair = Sign.KeyPair(publicKey: Bytes(proto.publicKey), secretKey: Bytes(proto.privateKey))
// Store it
SNLog("Received a new closed group authentication key pair.")
return Storage.shared.addClosedGroupAuthenticationKeyPair(keyPair, for: groupPublicKey, timestamp: timestamp, using: transaction)
}
private static func handleClosedGroupNameChanged(_ message: ClosedGroupControlMessage, using transaction: Any) {

Loading…
Cancel
Save