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

import Foundation
import MullvadTypes
import NetworkExtension
import WireGuardKitTypes

// swiftlint:disable function_parameter_count
public protocol PostQuantumKeyNegotiating {
    func startNegotiation(
        gatewayIP: IPv4Address,
        devicePublicKey: PublicKey,
        presharedKey: PrivateKey,
        postQuantumKeyReceiver: any TunnelProvider,
        tcpConnection: NWTCPConnection,
        postQuantumKeyExchangeTimeout: Duration
    ) -> Bool

    func cancelKeyNegotiation()

    init()
}

/**
 Attempt to start the asynchronous process of key negotiation. Returns true if successfully started, false if failed.
 */
public class PostQuantumKeyNegotiator: PostQuantumKeyNegotiating {
    required public init() {}

    var cancelToken: PostQuantumCancelToken?

    public func startNegotiation(
        gatewayIP: IPv4Address,
        devicePublicKey: PublicKey,
        presharedKey: PrivateKey,
        postQuantumKeyReceiver: any TunnelProvider,
        tcpConnection: NWTCPConnection,
        postQuantumKeyExchangeTimeout: Duration
    ) -> Bool {
        // swiftlint:disable:next force_cast
        let postQuantumKeyReceiver = Unmanaged.passUnretained(postQuantumKeyReceiver as! PostQuantumKeyReceiver)
            .toOpaque()
        let opaqueConnection = Unmanaged.passUnretained(tcpConnection).toOpaque()
        var cancelToken = PostQuantumCancelToken()

        let result = negotiate_post_quantum_key(
            devicePublicKey.rawValue.map { $0 },
            presharedKey.rawValue.map { $0 },
            postQuantumKeyReceiver,
            opaqueConnection,
            &cancelToken,
            UInt64(postQuantumKeyExchangeTimeout.timeInterval)
        )
        guard result == 0 else {
            return false
        }
        self.cancelToken = cancelToken
        return true
    }

    public func cancelKeyNegotiation() {
        guard var cancelToken else { return }
        cancel_post_quantum_key_exchange(&cancelToken)
    }

    deinit {
        guard var cancelToken else { return }
        drop_post_quantum_key_exchange_token(&cancelToken)
    }
}

// swiftlint:enable function_parameter_count