summaryrefslogtreecommitdiffhomepage
path: root/ios/MullvadRustRuntime/EphemeralPeerNegotiator.swift
blob: 5c12d7fe11a002907078b9e834bca5c258be19ba (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
//
//  PostQuantumKeyNegotiator.swift
//  PacketTunnel
//
//  Created by Marco Nikic on 2024-02-16.
//  Copyright © 2025 Mullvad VPN AB. All rights reserved.
//

import Foundation
import MullvadTypes
import NetworkExtension
import WireGuardKitTypes

public protocol EphemeralPeerNegotiating {
    func startNegotiation(
        devicePublicKey: PublicKey,
        presharedKey: PrivateKey,
        peerReceiver: any TunnelProvider,
        ephemeralPeerParams: EphemeralPeerParameters
    ) -> Bool

    func cancelKeyNegotiation()

    init()
}

/// Requests an ephemeral peer asynchronously.
public class EphemeralPeerNegotiator: EphemeralPeerNegotiating {
    required public init() {}

    var cancelToken: OpaquePointer?

    public func startNegotiation(
        devicePublicKey: PublicKey,
        presharedKey: PrivateKey,
        peerReceiver: any TunnelProvider,
        ephemeralPeerParams: EphemeralPeerParameters
    ) -> Bool {
        let ephemeralPeerReceiver = Unmanaged.passUnretained(peerReceiver as! EphemeralPeerReceiver)
            .toOpaque()

        guard let tunnelHandle = try? peerReceiver.tunnelHandle() else {
            return false
        }

        let cancelToken = request_ephemeral_peer(
            devicePublicKey.rawValue.map { $0 },
            presharedKey.rawValue.map { $0 },
            ephemeralPeerReceiver,
            tunnelHandle,
            ephemeralPeerParams
        )
        guard let cancelToken else {
            return false
        }
        self.cancelToken = cancelToken
        return true
    }

    public func cancelKeyNegotiation() {
        guard let cancelToken else { return }
        cancel_ephemeral_peer_exchange(cancelToken)
        self.cancelToken = nil
    }

    deinit {
        guard let cancelToken else { return }
        drop_ephemeral_peer_exchange_token(cancelToken)
    }
}