summaryrefslogtreecommitdiffhomepage
path: root/ios/PacketTunnel/PostQuantum/SingleHopEphemeralPeerExchanger.swift
blob: 170105ba907e54b0e6bd48d0e747615e2898ae79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//
//  SingleHopPostQuantumKeyExchanging.swift
//  PacketTunnel
//
//  Created by Mojgan on 2024-07-15.
//  Copyright © 2025 Mullvad VPN AB. All rights reserved.
//

import MullvadREST
import MullvadRustRuntime
import MullvadSettings
import MullvadTypes
import PacketTunnelCore
import WireGuardKitTypes

struct SingleHopEphemeralPeerExchanger: EphemeralPeerExchangingProtocol {
    let exit: SelectedRelay
    let keyExchanger: EphemeralPeerExchangeActorProtocol
    let devicePrivateKey: PrivateKey
    let onFinish: () -> Void
    let onUpdateConfiguration: (EphemeralPeerNegotiationState) async -> Void
    let enablePostQuantum: Bool
    let enableDaita: Bool

    init(
        exit: SelectedRelay,
        devicePrivateKey: PrivateKey,
        keyExchanger: EphemeralPeerExchangeActorProtocol,
        enablePostQuantum: Bool,
        enableDaita: Bool,
        onUpdateConfiguration: @escaping (EphemeralPeerNegotiationState) async -> Void,
        onFinish: @escaping () -> Void
    ) {
        self.devicePrivateKey = devicePrivateKey
        self.exit = exit
        self.keyExchanger = keyExchanger
        self.enablePostQuantum = enablePostQuantum
        self.enableDaita = enableDaita
        self.onUpdateConfiguration = onUpdateConfiguration
        self.onFinish = onFinish
    }

    func start() async {
        await onUpdateConfiguration(
            .single(
                EphemeralPeerRelayConfiguration(
                    relay: exit,
                    configuration: EphemeralPeerConfiguration(
                        privateKey: devicePrivateKey,
                        allowedIPs: [IPAddressRange(from: "\(LocalNetworkIPs.gatewayAddress.rawValue)/32")!],
                        daitaParameters: nil
                    )
                )))
        keyExchanger.startNegotiation(
            with: devicePrivateKey,
            enablePostQuantum: enablePostQuantum,
            enableDaita: enableDaita
        )
    }

    public func receiveEphemeralPeerPrivateKey(_ ephemeralKey: PrivateKey, daitaParameters: DaitaV2Parameters?) async {
        await onUpdateConfiguration(
            .single(
                EphemeralPeerRelayConfiguration(
                    relay: exit,
                    configuration: EphemeralPeerConfiguration(
                        privateKey: ephemeralKey,
                        preSharedKey: nil,
                        allowedIPs: [
                            IPAddressRange(from: "\(LocalNetworkIPs.defaultRouteIpV4.rawValue)/0")!,
                            IPAddressRange(from: "\(LocalNetworkIPs.defaultRouteIpV6.rawValue)/0")!,
                        ],
                        daitaParameters: daitaParameters
                    )
                )))
        self.onFinish()
    }

    func receivePostQuantumKey(
        _ preSharedKey: WireGuardKitTypes.PreSharedKey,
        ephemeralKey: WireGuardKitTypes.PrivateKey,
        daitaParameters: DaitaV2Parameters?
    ) async {
        await onUpdateConfiguration(
            .single(
                EphemeralPeerRelayConfiguration(
                    relay: exit,
                    configuration: EphemeralPeerConfiguration(
                        privateKey: ephemeralKey,
                        preSharedKey: preSharedKey,
                        allowedIPs: [
                            IPAddressRange(from: "\(LocalNetworkIPs.defaultRouteIpV4.rawValue)/0")!,
                            IPAddressRange(from: "\(LocalNetworkIPs.defaultRouteIpV6.rawValue)/0")!,
                        ],
                        daitaParameters: daitaParameters
                    )
                )))
        self.onFinish()
    }
}