Skip to content

Commit

Permalink
Fix a clippy warning and add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
buggmagnet committed Aug 27, 2024
1 parent 63e78ad commit e84a7a7
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 42 deletions.
12 changes: 6 additions & 6 deletions ios/MullvadVPN.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@
F072D3D22C071AD100906F64 /* ShadowsocksLoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F072D3D12C071AD100906F64 /* ShadowsocksLoaderTests.swift */; };
F073FCB32C6617D70062EA1D /* TunnelStore+Stubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = F073FCB22C6617D70062EA1D /* TunnelStore+Stubs.swift */; };
F07751552C50F149006E6A12 /* EphemeralPeerExchangeActorStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C4C9BF2C495E7500A79006 /* EphemeralPeerExchangeActorStub.swift */; };
F07751572C50F149006E6A12 /* PostQuantumKeyExchangingPipelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F053F4B92C4A94D300FBD937 /* PostQuantumKeyExchangingPipelineTests.swift */; };
F07751572C50F149006E6A12 /* EphemeralPeerExchangingPipelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F053F4B92C4A94D300FBD937 /* EphemeralPeerExchangingPipelineTests.swift */; };
F07751582C50F149006E6A12 /* MultiHopEphemeralPeerExchangerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C4C9BD2C49477B00A79006 /* MultiHopEphemeralPeerExchangerTests.swift */; };
F07751592C50F149006E6A12 /* SingleHopEphemeralPeerExchangerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0A163882C47B46300592300 /* SingleHopEphemeralPeerExchangerTests.swift */; };
F07B53572C53B5270024F547 /* LocalNetworkIPs.swift in Sources */ = {isa = PBXBuildFile; fileRef = F07B53562C53B5270024F547 /* LocalNetworkIPs.swift */; };
Expand Down Expand Up @@ -2087,7 +2087,7 @@
F050AE5D2B739A73003F4EDB /* LocationDataSourceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationDataSourceProtocol.swift; sourceTree = "<group>"; };
F050AE5F2B73A41E003F4EDB /* AllLocationDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllLocationDataSource.swift; sourceTree = "<group>"; };
F050AE612B74DBAC003F4EDB /* CustomListsDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomListsDataSource.swift; sourceTree = "<group>"; };
F053F4B92C4A94D300FBD937 /* PostQuantumKeyExchangingPipelineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostQuantumKeyExchangingPipelineTests.swift; sourceTree = "<group>"; };
F053F4B92C4A94D300FBD937 /* EphemeralPeerExchangingPipelineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EphemeralPeerExchangingPipelineTests.swift; sourceTree = "<group>"; };
F05769B82C6656E400D9778B /* TunnelSettingsPropagator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelSettingsPropagator.swift; sourceTree = "<group>"; };
F05769BA2C6661EE00D9778B /* TunnelSettingsStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelSettingsStrategy.swift; sourceTree = "<group>"; };
F05919742C45194B00C301F3 /* EphemeralPeerKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EphemeralPeerKey.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3362,14 +3362,12 @@
isa = PBXGroup;
children = (
7A3FD1B42AD4465A0042BEA6 /* AppMessageHandlerTests.swift */,
F053F4B92C4A94D300FBD937 /* EphemeralPeerExchangingPipelineTests.swift */,
586C14572AC463BB00245C01 /* EventChannelTests.swift */,
F0FBD98E2C4A60CC00EE5323 /* KeyExchangingResultStub.swift */,
58EC067D2A8D2B0700BEB973 /* Mocks */,
F0C4C9BD2C49477B00A79006 /* MultiHopEphemeralPeerExchangerTests.swift */,
58FE25D32AA729B5003D1918 /* PacketTunnelActorTests.swift */,
58C7A46F2A8649ED0060C66F /* PingerTests.swift */,
F0C4C9BF2C495E7500A79006 /* EphemeralPeerExchangeActorStub.swift */,
F053F4B92C4A94D300FBD937 /* PostQuantumKeyExchangingPipelineTests.swift */,
A97D25B12B0CB02D00946B2D /* ProtocolObfuscatorTests.swift */,
F0A163882C47B46300592300 /* SingleHopEphemeralPeerExchangerTests.swift */,
5838321C2AC1C54600EA2071 /* TaskSleepTests.swift */,
Expand Down Expand Up @@ -3659,6 +3657,8 @@
children = (
58F7753C2AB8473200425B47 /* BlockedStateErrorMapperStub.swift */,
581F23AC2A8CF92100788AB6 /* DefaultPathObserverFake.swift */,
F0C4C9BF2C495E7500A79006 /* EphemeralPeerExchangeActorStub.swift */,
F0FBD98E2C4A60CC00EE5323 /* KeyExchangingResultStub.swift */,
58EC067B2A8D2A0B00BEB973 /* NetworkCounters.swift */,
5838321A2AC1B18400EA2071 /* PacketTunnelActor+Mocks.swift */,
7AD0AA1B2AD6A63F00119E10 /* PacketTunnelActorStub.swift */,
Expand Down Expand Up @@ -5531,7 +5531,7 @@
F0ACE3372BE517F1006D5333 /* ServerRelaysResponse+Stubs.swift in Sources */,
58F7753D2AB8473200425B47 /* BlockedStateErrorMapperStub.swift in Sources */,
58FE25D42AA729B5003D1918 /* PacketTunnelActorTests.swift in Sources */,
F07751572C50F149006E6A12 /* PostQuantumKeyExchangingPipelineTests.swift in Sources */,
F07751572C50F149006E6A12 /* EphemeralPeerExchangingPipelineTests.swift in Sources */,
7A3FD1B52AD4465A0042BEA6 /* AppMessageHandlerTests.swift in Sources */,
58C7A4702A8649ED0060C66F /* PingerTests.swift in Sources */,
A97D25B22B0CB02D00946B2D /* ProtocolObfuscatorTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// PostQuantumKeyExchangingPipelineTests.swift
// EphemeralPeerExchangingPipelineTests.swift
// MullvadPostQuantumTests
//
// Created by Mojgan on 2024-07-19.
Expand All @@ -13,7 +13,7 @@
@testable import WireGuardKitTypes
import XCTest

final class PostQuantumKeyExchangingPipelineTests: XCTestCase {
final class EphemeralPeerExchangingPipelineTests: XCTestCase {
var entryRelay: SelectedRelay!
var exitRelay: SelectedRelay!
var relayConstraints: RelayConstraints!
Expand Down Expand Up @@ -60,7 +60,7 @@ final class PostQuantumKeyExchangingPipelineTests: XCTestCase {
)
}

func testSingleHopKeyExchange() throws {
func testSingleHopPostQuantumKeyExchange() throws {
let reconfigurationExpectation = expectation(description: "Tunnel reconfiguration took place")
reconfigurationExpectation.expectedFulfillmentCount = 2

Expand All @@ -81,17 +81,37 @@ final class PostQuantumKeyExchangingPipelineTests: XCTestCase {
postQuantumKeyExchangingPipeline.receivePostQuantumKey(preSharedKey, ephemeralKey: privateKey)
})

let connectionState = ObservedConnectionState(
selectedRelays: SelectedRelays(entry: nil, exit: exitRelay, retryAttempt: 0),
relayConstraints: relayConstraints,
networkReachability: NetworkReachability.reachable,
connectionAttemptCount: 0,
transportLayer: .udp,
remotePort: 1234,
isPostQuantum: true,
isDaitaEnabled: false
let connectionState = stubConnectionState(enableMultiHop: false, enablePostQuantum: true, enableDaita: false)
postQuantumKeyExchangingPipeline.startNegotiation(connectionState, privateKey: PrivateKey())

wait(
for: [reconfigurationExpectation, negotiationSuccessful],
timeout: .UnitTest.invertedTimeout
)
}

func testSingleHopDaitaPeerExchange() throws {
let reconfigurationExpectation = expectation(description: "Tunnel reconfiguration took place")
reconfigurationExpectation.expectedFulfillmentCount = 2

let negotiationSuccessful = expectation(description: "Negotiation succeeded.")
negotiationSuccessful.expectedFulfillmentCount = 1

let keyExchangeActor = EphemeralPeerExchangeActorStub()
let preSharedKey = try XCTUnwrap(PreSharedKey(hexKey: PrivateKey().hexKey))
keyExchangeActor.result = .success((preSharedKey, PrivateKey()))

let postQuantumKeyExchangingPipeline = EphemeralPeerExchangingPipeline(keyExchangeActor) { _ in
reconfigurationExpectation.fulfill()
} onFinish: {
negotiationSuccessful.fulfill()
}

keyExchangeActor.delegate = KeyExchangingResultStub(onReceiveEphemeralPeerPrivateKey: { privateKey in
postQuantumKeyExchangingPipeline.receiveEphemeralPeerPrivateKey(privateKey)
})

let connectionState = stubConnectionState(enableMultiHop: false, enablePostQuantum: false, enableDaita: true)
postQuantumKeyExchangingPipeline.startNegotiation(connectionState, privateKey: PrivateKey())

wait(
Expand All @@ -100,7 +120,7 @@ final class PostQuantumKeyExchangingPipelineTests: XCTestCase {
)
}

func testMultiHopKeyExchange() throws {
func testMultiHopPostQuantumKeyExchange() throws {
let reconfigurationExpectation = expectation(description: "Tunnel reconfiguration took place")
reconfigurationExpectation.expectedFulfillmentCount = 3

Expand All @@ -121,22 +141,59 @@ final class PostQuantumKeyExchangingPipelineTests: XCTestCase {
postQuantumKeyExchangingPipeline.receivePostQuantumKey(preSharedKey, ephemeralKey: privateKey)
})

let connectionState = ObservedConnectionState(
selectedRelays: SelectedRelays(entry: entryRelay, exit: exitRelay, retryAttempt: 0),
relayConstraints: relayConstraints,
networkReachability: NetworkReachability.reachable,
connectionAttemptCount: 0,
transportLayer: .udp,
remotePort: 1234,
isPostQuantum: true,
isDaitaEnabled: false
let connectionState = stubConnectionState(enableMultiHop: true, enablePostQuantum: true, enableDaita: false)
postQuantumKeyExchangingPipeline.startNegotiation(connectionState, privateKey: PrivateKey())

wait(
for: [reconfigurationExpectation, negotiationSuccessful],
timeout: .UnitTest.invertedTimeout
)
}

func testMultiHopDaitaExchange() throws {
let reconfigurationExpectation = expectation(description: "Tunnel reconfiguration took place")
reconfigurationExpectation.expectedFulfillmentCount = 3

let negotiationSuccessful = expectation(description: "Negotiation succeeded.")
negotiationSuccessful.expectedFulfillmentCount = 1

let keyExchangeActor = EphemeralPeerExchangeActorStub()
let preSharedKey = try XCTUnwrap(PreSharedKey(hexKey: PrivateKey().hexKey))
keyExchangeActor.result = .success((preSharedKey, PrivateKey()))

let postQuantumKeyExchangingPipeline = EphemeralPeerExchangingPipeline(keyExchangeActor) { _ in
reconfigurationExpectation.fulfill()
} onFinish: {
negotiationSuccessful.fulfill()
}

keyExchangeActor.delegate = KeyExchangingResultStub(onReceiveEphemeralPeerPrivateKey: { privateKey in
postQuantumKeyExchangingPipeline.receiveEphemeralPeerPrivateKey(privateKey)
})

let connectionState = stubConnectionState(enableMultiHop: true, enablePostQuantum: false, enableDaita: true)
postQuantumKeyExchangingPipeline.startNegotiation(connectionState, privateKey: PrivateKey())

wait(
for: [reconfigurationExpectation, negotiationSuccessful],
timeout: .UnitTest.invertedTimeout
)
}

func stubConnectionState(
enableMultiHop: Bool,
enablePostQuantum: Bool,
enableDaita: Bool
) -> ObservedConnectionState {
ObservedConnectionState(
selectedRelays: SelectedRelays(entry: enableMultiHop ? entryRelay : nil, exit: exitRelay, retryAttempt: 0),
relayConstraints: relayConstraints,
networkReachability: NetworkReachability.reachable,
connectionAttemptCount: 0,
transportLayer: .udp,
remotePort: 1234,
isPostQuantum: enablePostQuantum,
isDaitaEnabled: enableDaita
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ final class MultiHopEphemeralPeerExchangerTests: XCTestCase {
)
}

// TODO: Write more tests
func testEphemeralPeerExchangeSuccessWhenDaitaNegotiationStarts() throws {
let unexpectedNegotiationFailure = expectation(description: "Negotiation failed.")
unexpectedNegotiationFailure.isInverted = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ final class SingleHopEphemeralPeerExchangerTests: XCTestCase {
exitRelay = SelectedRelay(endpoint: match.endpoint, hostname: match.relay.hostname, location: match.location)
}

func testKeyExchangeFailsWhenNegotiationCannotStart() {
func testEphemeralPeerExchangeFailsWhenNegotiationCannotStart() {
let expectedNegotiationFailure = expectation(description: "Negotiation failed.")

let reconfigurationExpectation = expectation(description: "Tunnel reconfiguration took place")
Expand Down Expand Up @@ -74,7 +74,7 @@ final class SingleHopEphemeralPeerExchangerTests: XCTestCase {
)
}

func testKeyExchangeSuccessWhenNegotiationStart() throws {
func testEphemeralPeerExchangeSuccessWhenPostQuantumNegotiationStarts() throws {
let unexpectedNegotiationFailure = expectation(description: "Negotiation failed.")
unexpectedNegotiationFailure.isInverted = true

Expand Down Expand Up @@ -110,4 +110,41 @@ final class SingleHopEphemeralPeerExchangerTests: XCTestCase {
timeout: .UnitTest.invertedTimeout
)
}

func testEphemeralPeerExchangeSuccessWhenDaitaNegotiationStarts() throws {
let unexpectedNegotiationFailure = expectation(description: "Negotiation failed.")
unexpectedNegotiationFailure.isInverted = true

let reconfigurationExpectation = expectation(description: "Tunnel reconfiguration took place")
reconfigurationExpectation.expectedFulfillmentCount = 2

let negotiationSuccessful = expectation(description: "Negotiation succeeded.")
negotiationSuccessful.expectedFulfillmentCount = 1

let peerExchangeActor = EphemeralPeerExchangeActorStub()
let preSharedKey = try XCTUnwrap(PreSharedKey(hexKey: PrivateKey().hexKey))
peerExchangeActor.result = .success((preSharedKey, PrivateKey()))

let multiHopPeerExchanger = SingleHopEphemeralPeerExchanger(
exit: exitRelay,
devicePrivateKey: PrivateKey(),
keyExchanger: peerExchangeActor,
enablePostQuantum: false,
enableDaita: true
) { _ in
reconfigurationExpectation.fulfill()
} onFinish: {
negotiationSuccessful.fulfill()
}

peerExchangeActor.delegate = KeyExchangingResultStub(onReceiveEphemeralPeerPrivateKey: { ephemeralKey in
multiHopPeerExchanger.receiveEphemeralPeerPrivateKey(ephemeralKey)
})
multiHopPeerExchanger.start()

wait(
for: [unexpectedNegotiationFailure, reconfigurationExpectation, negotiationSuccessful],
timeout: .UnitTest.invertedTimeout
)
}
}
9 changes: 8 additions & 1 deletion mullvad-ios/src/post_quantum_proxy/ios_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ pub unsafe fn run_post_quantum_psk_exchange(
packet_tunnel: *const c_void,
tcp_connection: *const c_void,
peer_exchange_timeout: u64,
tokio_handle: TokioHandle,
enable_post_quantum: bool,
enable_daita: bool,
) -> Result<EphemeralPeerCancelToken, Error> {
Expand All @@ -40,6 +39,14 @@ pub unsafe fn run_post_quantum_psk_exchange(
Ok(runtime) => {
let token = runtime.packet_tunnel.tcp_connection.clone();

let tokio_handle = match crate::mullvad_ios_runtime() {
Ok(handle) => handle,
Err(err) => {
log::error!("Failed to obtain a handle to a tokio runtime: {err}");
return Err(Error::UnableToCreateRuntime);
}
};

runtime.run(tokio_handle);
Ok(EphemeralPeerCancelToken {
context: Arc::into_raw(token) as *mut _,
Expand Down
10 changes: 0 additions & 10 deletions mullvad-ios/src/post_quantum_proxy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,23 +137,13 @@ pub unsafe extern "C" fn request_ephemeral_peer(
let pub_key: [u8; 32] = unsafe { std::ptr::read(public_key as *const [u8; 32]) };
let eph_key: [u8; 32] = unsafe { std::ptr::read(ephemeral_key as *const [u8; 32]) };

let handle = match crate::mullvad_ios_runtime() {
Ok(handle) => handle,
Err(err) => {
log::error!("Failed to obtain a handle to a tokio runtime: {err}");

return -1;
}
};

match unsafe {
run_post_quantum_psk_exchange(
pub_key,
eph_key,
packet_tunnel,
tcp_connection,
peer_exchange_timeout,
handle,
enable_post_quantum,
enable_daita,
)
Expand Down

0 comments on commit e84a7a7

Please sign in to comment.