Skip to content

Commit 955f7a8

Browse files
authored
Export sender ratchet key (#9)
* feat: exported sender ratchet public key for the message * feat: exported current ratchet public key for the session
1 parent 8a454df commit 955f7a8

4 files changed

Lines changed: 72 additions & 0 deletions

File tree

Sources/DXProtocol/Messages/MessageContainer.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ extension MessageContainer: Codable {
4747
case secureMessage
4848
case preKeySecureMessage
4949
}
50+
51+
/// The public key of the ratchet key pair from sending chain which was used to encrypt this message
52+
public var senderRatchetKey: PublicKey {
53+
let result: PublicKey
54+
55+
switch self {
56+
case .secureMessage(let message):
57+
result = message.senderRatchetKey
58+
case .preKeySecureMessage(let message):
59+
result = message.secureMessage.senderRatchetKey
60+
}
61+
62+
return result
63+
}
5064

5165
/// Initializes a `MessageContainer` struct from a decoder.
5266
///

Sources/DXProtocol/Session/Session.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,11 @@ extension Session {
485485
self.state.archived = true
486486
self.previousSessionStates.insert(self.state, at: 0)
487487
}
488+
489+
/// Returns public key of the current sender ratchet key pair
490+
public func currentSenderRatchetKey() -> PublicKey {
491+
self.state.senderChain.ratchetKeyPair.publicKey
492+
}
488493

489494
/// Makes the specified state the currently active state of the session.
490495
/// This method must be used to promote newly created states to existing sessions

Tests/DXProtocolTests/MessagesTests/MessageContainerTests.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,48 @@ import XCTest
2727
@testable import DXProtocol
2828

2929
final class MessageContainerTests: XCTestCase {
30+
func testSenderRatchetKey() throws {
31+
let aliceRatchetKey = try KeyPair().publicKey
32+
let aliceBaseKey = try KeyPair().publicKey
33+
let aliceIdentityKey = IdentityKeyPublic(publicKey: try KeyPair().publicKey)
34+
let bobIdentityKey = IdentityKeyPublic(publicKey: try KeyPair().publicKey)
35+
let macKeyData = Data([
36+
0xce, 0x41, 0x35, 0xc2, 0x19, 0xb1, 0xdb, 0xe2, 0xfa, 0x66, 0x6d, 0xdf, 0xb3, 0x9a, 0x7e,
37+
0x46, 0x7b, 0xd8, 0x33, 0xf9, 0xcf, 0x30, 0xd9, 0x9d, 0x96, 0x0e, 0xe7, 0x38, 0x07, 0x25,
38+
0xa7, 0xf1
39+
])
40+
41+
let registrationId = UUID()
42+
let oneTimePreKeyId = UUID()
43+
let signedPreKeyId = UUID()
44+
45+
let content = "DXProtocolSecureMessage"
46+
let data = Data(content.utf8)
47+
48+
let secureMessage = try SecureMessage(
49+
messageVersion: DXProtocolConstants.cipertextMessageCurrentVersion,
50+
macKey: macKeyData,
51+
senderRatchetKey: aliceRatchetKey,
52+
counter: 3,
53+
previousCounter: 2,
54+
encrypted: data,
55+
senderIdentityKey: aliceIdentityKey,
56+
receiverIdentityKey: bobIdentityKey)
57+
var container = MessageContainer.secureMessage(secureMessage)
58+
XCTAssertEqual(container.senderRatchetKey, aliceRatchetKey)
59+
60+
let preKeyMessage = try PreKeySecureMessage(
61+
messageVersion: DXProtocolConstants.cipertextMessageCurrentVersion,
62+
registrationId: registrationId,
63+
oneTimePreKeyId: oneTimePreKeyId,
64+
signedPreKeyId: signedPreKeyId,
65+
senderBaseKey: aliceBaseKey,
66+
senderIdentityKey: aliceIdentityKey,
67+
secureMessage: secureMessage)
68+
container = MessageContainer.preKeySecureMessage(preKeyMessage)
69+
XCTAssertEqual(container.senderRatchetKey, aliceRatchetKey)
70+
}
71+
3072
func testSerializeDeserializeSecureMessage() throws {
3173
let aliceRatchetKey = try KeyPair().publicKey
3274
let aliceIdentityKey = IdentityKeyPublic(publicKey: try KeyPair().publicKey)

Tests/DXProtocolTests/SessionTests/SessionTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,17 @@ final class SessionTests: XCTestCase {
531531
XCTAssertFalse(session.hasCurrentState())
532532
XCTAssertEqual(session.previousSessionStates.count, 1)
533533
}
534+
535+
func testCurrentSenderRatchetKey() throws {
536+
let senderClient = try TestClient(userId: UUID()) // Alice
537+
let recipientClient = try TestClient(userId: UUID()) // Bob
538+
try initializeSession(senderClient: senderClient, recipientClient: recipientClient)
539+
540+
let session = try recipientClient.sessionStore.loadSession(for: senderClient.protocolAddress)
541+
let expectedRatchetKey = try XCTUnwrap(session?.state.senderChain.ratchetKeyPair.publicKey)
542+
XCTAssertEqual(expectedRatchetKey, session?.currentSenderRatchetKey())
543+
}
544+
534545
// FIXME: - Need fix
535546
func testBasicSessionInteraction() throws {
536547
let senderClient = try TestClient(userId: UUID()) // Alice

0 commit comments

Comments
 (0)