diff options
Diffstat (limited to 'WireGuard/Shared/Model')
-rw-r--r-- | WireGuard/Shared/Model/DNSServer.swift | 35 | ||||
-rw-r--r-- | WireGuard/Shared/Model/Data+KeyEncoding.swift | 80 | ||||
-rw-r--r-- | WireGuard/Shared/Model/Endpoint.swift | 100 | ||||
-rw-r--r-- | WireGuard/Shared/Model/IPAddressRange.swift | 67 | ||||
-rw-r--r-- | WireGuard/Shared/Model/InterfaceConfiguration.swift | 33 | ||||
-rw-r--r-- | WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift | 87 | ||||
-rw-r--r-- | WireGuard/Shared/Model/PeerConfiguration.swift | 51 | ||||
-rw-r--r-- | WireGuard/Shared/Model/String+ArrayConversion.swift | 32 | ||||
-rw-r--r-- | WireGuard/Shared/Model/TunnelConfiguration+WgQuickConfig.swift | 251 | ||||
-rw-r--r-- | WireGuard/Shared/Model/TunnelConfiguration.swift | 32 | ||||
-rw-r--r-- | WireGuard/Shared/Model/key.c | 114 | ||||
-rw-r--r-- | WireGuard/Shared/Model/key.h | 22 |
12 files changed, 0 insertions, 904 deletions
diff --git a/WireGuard/Shared/Model/DNSServer.swift b/WireGuard/Shared/Model/DNSServer.swift deleted file mode 100644 index 0d03577..0000000 --- a/WireGuard/Shared/Model/DNSServer.swift +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import Foundation -import Network - -struct DNSServer { - let address: IPAddress - - init(address: IPAddress) { - self.address = address - } -} - -extension DNSServer: Equatable { - static func == (lhs: DNSServer, rhs: DNSServer) -> Bool { - return lhs.address.rawValue == rhs.address.rawValue - } -} - -extension DNSServer { - var stringRepresentation: String { - return "\(address)" - } - - init?(from addressString: String) { - if let addr = IPv4Address(addressString) { - address = addr - } else if let addr = IPv6Address(addressString) { - address = addr - } else { - return nil - } - } -} diff --git a/WireGuard/Shared/Model/Data+KeyEncoding.swift b/WireGuard/Shared/Model/Data+KeyEncoding.swift deleted file mode 100644 index 5c7aee9..0000000 --- a/WireGuard/Shared/Model/Data+KeyEncoding.swift +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import Foundation - -extension Data { - func isKey() -> Bool { - return self.count == WG_KEY_LEN - } - - func hexKey() -> String? { - if self.count != WG_KEY_LEN { - return nil - } - var out = Data(repeating: 0, count: Int(WG_KEY_LEN_HEX)) - out.withUnsafeMutableInt8Bytes { outBytes in - self.withUnsafeUInt8Bytes { inBytes in - key_to_hex(outBytes, inBytes) - } - } - out.removeLast() - return String(data: out, encoding: .ascii) - } - - init?(hexKey hexString: String) { - self.init(repeating: 0, count: Int(WG_KEY_LEN)) - - if !self.withUnsafeMutableUInt8Bytes { key_from_hex($0, hexString) } { - return nil - } - } - - func base64Key() -> String? { - if self.count != WG_KEY_LEN { - return nil - } - var out = Data(repeating: 0, count: Int(WG_KEY_LEN_BASE64)) - out.withUnsafeMutableInt8Bytes { outBytes in - self.withUnsafeUInt8Bytes { inBytes in - key_to_base64(outBytes, inBytes) - } - } - out.removeLast() - return String(data: out, encoding: .ascii) - } - - init?(base64Key base64String: String) { - self.init(repeating: 0, count: Int(WG_KEY_LEN)) - - if !self.withUnsafeMutableUInt8Bytes { key_from_base64($0, base64String) } { - return nil - } - } -} - -extension Data { - func withUnsafeUInt8Bytes<R>(_ body: (UnsafePointer<UInt8>) -> R) -> R { - assert(!isEmpty) - return self.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> R in - let bytes = ptr.bindMemory(to: UInt8.self) - return body(bytes.baseAddress!) // might crash if self.count == 0 - } - } - - mutating func withUnsafeMutableUInt8Bytes<R>(_ body: (UnsafeMutablePointer<UInt8>) -> R) -> R { - assert(!isEmpty) - return self.withUnsafeMutableBytes { (ptr: UnsafeMutableRawBufferPointer) -> R in - let bytes = ptr.bindMemory(to: UInt8.self) - return body(bytes.baseAddress!) // might crash if self.count == 0 - } - } - - mutating func withUnsafeMutableInt8Bytes<R>(_ body: (UnsafeMutablePointer<Int8>) -> R) -> R { - assert(!isEmpty) - return self.withUnsafeMutableBytes { (ptr: UnsafeMutableRawBufferPointer) -> R in - let bytes = ptr.bindMemory(to: Int8.self) - return body(bytes.baseAddress!) // might crash if self.count == 0 - } - } -} diff --git a/WireGuard/Shared/Model/Endpoint.swift b/WireGuard/Shared/Model/Endpoint.swift deleted file mode 100644 index dad5961..0000000 --- a/WireGuard/Shared/Model/Endpoint.swift +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import Foundation -import Network - -struct Endpoint { - let host: NWEndpoint.Host - let port: NWEndpoint.Port - - init(host: NWEndpoint.Host, port: NWEndpoint.Port) { - self.host = host - self.port = port - } -} - -extension Endpoint: Equatable { - static func == (lhs: Endpoint, rhs: Endpoint) -> Bool { - return lhs.host == rhs.host && lhs.port == rhs.port - } -} - -extension Endpoint: Hashable { - func hash(into hasher: inout Hasher) { - hasher.combine(host) - hasher.combine(port) - } -} - -extension Endpoint { - var stringRepresentation: String { - switch host { - case .name(let hostname, _): - return "\(hostname):\(port)" - case .ipv4(let address): - return "\(address):\(port)" - case .ipv6(let address): - return "[\(address)]:\(port)" - @unknown default: - fatalError() - } - } - - init?(from string: String) { - // Separation of host and port is based on 'parse_endpoint' function in - // https://git.zx2c4.com/wireguard-tools/tree/src/config.c - guard !string.isEmpty else { return nil } - let startOfPort: String.Index - let hostString: String - if string.first! == "[" { - // Look for IPv6-style endpoint, like [::1]:80 - let startOfHost = string.index(after: string.startIndex) - guard let endOfHost = string.dropFirst().firstIndex(of: "]") else { return nil } - let afterEndOfHost = string.index(after: endOfHost) - guard string[afterEndOfHost] == ":" else { return nil } - startOfPort = string.index(after: afterEndOfHost) - hostString = String(string[startOfHost ..< endOfHost]) - } else { - // Look for an IPv4-style endpoint, like 127.0.0.1:80 - guard let endOfHost = string.firstIndex(of: ":") else { return nil } - startOfPort = string.index(after: endOfHost) - hostString = String(string[string.startIndex ..< endOfHost]) - } - guard let endpointPort = NWEndpoint.Port(String(string[startOfPort ..< string.endIndex])) else { return nil } - let invalidCharacterIndex = hostString.unicodeScalars.firstIndex { char in - return !CharacterSet.urlHostAllowed.contains(char) - } - guard invalidCharacterIndex == nil else { return nil } - host = NWEndpoint.Host(hostString) - port = endpointPort - } -} - -extension Endpoint { - func hasHostAsIPAddress() -> Bool { - switch host { - case .name: - return false - case .ipv4: - return true - case .ipv6: - return true - @unknown default: - fatalError() - } - } - - func hostname() -> String? { - switch host { - case .name(let hostname, _): - return hostname - case .ipv4: - return nil - case .ipv6: - return nil - @unknown default: - fatalError() - } - } -} diff --git a/WireGuard/Shared/Model/IPAddressRange.swift b/WireGuard/Shared/Model/IPAddressRange.swift deleted file mode 100644 index d38686c..0000000 --- a/WireGuard/Shared/Model/IPAddressRange.swift +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import Foundation -import Network - -struct IPAddressRange { - let address: IPAddress - var networkPrefixLength: UInt8 - - init(address: IPAddress, networkPrefixLength: UInt8) { - self.address = address - self.networkPrefixLength = networkPrefixLength - } -} - -extension IPAddressRange: Equatable { - static func == (lhs: IPAddressRange, rhs: IPAddressRange) -> Bool { - return lhs.address.rawValue == rhs.address.rawValue && lhs.networkPrefixLength == rhs.networkPrefixLength - } -} - -extension IPAddressRange: Hashable { - func hash(into hasher: inout Hasher) { - hasher.combine(address.rawValue) - hasher.combine(networkPrefixLength) - } -} - -extension IPAddressRange { - var stringRepresentation: String { - return "\(address)/\(networkPrefixLength)" - } - - init?(from string: String) { - guard let parsed = IPAddressRange.parseAddressString(string) else { return nil } - address = parsed.0 - networkPrefixLength = parsed.1 - } - - private static func parseAddressString(_ string: String) -> (IPAddress, UInt8)? { - let endOfIPAddress = string.lastIndex(of: "/") ?? string.endIndex - let addressString = String(string[string.startIndex ..< endOfIPAddress]) - let address: IPAddress - if let addr = IPv4Address(addressString) { - address = addr - } else if let addr = IPv6Address(addressString) { - address = addr - } else { - return nil - } - - let maxNetworkPrefixLength: UInt8 = address is IPv4Address ? 32 : 128 - var networkPrefixLength: UInt8 - if endOfIPAddress < string.endIndex { // "/" was located - let indexOfNetworkPrefixLength = string.index(after: endOfIPAddress) - guard indexOfNetworkPrefixLength < string.endIndex else { return nil } - let networkPrefixLengthSubstring = string[indexOfNetworkPrefixLength ..< string.endIndex] - guard let npl = UInt8(networkPrefixLengthSubstring) else { return nil } - networkPrefixLength = min(npl, maxNetworkPrefixLength) - } else { - networkPrefixLength = maxNetworkPrefixLength - } - - return (address, networkPrefixLength) - } -} diff --git a/WireGuard/Shared/Model/InterfaceConfiguration.swift b/WireGuard/Shared/Model/InterfaceConfiguration.swift deleted file mode 100644 index d80ed89..0000000 --- a/WireGuard/Shared/Model/InterfaceConfiguration.swift +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import Foundation -import Network - -struct InterfaceConfiguration { - var privateKey: Data - var addresses = [IPAddressRange]() - var listenPort: UInt16? - var mtu: UInt16? - var dns = [DNSServer]() - - init(privateKey: Data) { - if privateKey.count != TunnelConfiguration.keyLength { - fatalError("Invalid private key") - } - self.privateKey = privateKey - } -} - -extension InterfaceConfiguration: Equatable { - static func == (lhs: InterfaceConfiguration, rhs: InterfaceConfiguration) -> Bool { - let lhsAddresses = lhs.addresses.filter { $0.address is IPv4Address } + lhs.addresses.filter { $0.address is IPv6Address } - let rhsAddresses = rhs.addresses.filter { $0.address is IPv4Address } + rhs.addresses.filter { $0.address is IPv6Address } - - return lhs.privateKey == rhs.privateKey && - lhsAddresses == rhsAddresses && - lhs.listenPort == rhs.listenPort && - lhs.mtu == rhs.mtu && - lhs.dns == rhs.dns - } -} diff --git a/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift b/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift deleted file mode 100644 index 7828d81..0000000 --- a/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import NetworkExtension - -enum PacketTunnelProviderError: String, Error { - case savedProtocolConfigurationIsInvalid - case dnsResolutionFailure - case couldNotStartBackend - case couldNotDetermineFileDescriptor - case couldNotSetNetworkSettings -} - -extension NETunnelProviderProtocol { - convenience init?(tunnelConfiguration: TunnelConfiguration, previouslyFrom old: NEVPNProtocol? = nil) { - self.init() - - guard let name = tunnelConfiguration.name else { return nil } - guard let appId = Bundle.main.bundleIdentifier else { return nil } - providerBundleIdentifier = "\(appId).network-extension" - passwordReference = Keychain.makeReference(containing: tunnelConfiguration.asWgQuickConfig(), called: name, previouslyReferencedBy: old?.passwordReference) - if passwordReference == nil { - return nil - } - #if os(macOS) - providerConfiguration = ["UID": getuid()] - #endif - - let endpoints = tunnelConfiguration.peers.compactMap { $0.endpoint } - if endpoints.count == 1 { - serverAddress = endpoints[0].stringRepresentation - } else if endpoints.isEmpty { - serverAddress = "Unspecified" - } else { - serverAddress = "Multiple endpoints" - } - } - - func asTunnelConfiguration(called name: String? = nil) -> TunnelConfiguration? { - if let passwordReference = passwordReference, - let config = Keychain.openReference(called: passwordReference) { - return try? TunnelConfiguration(fromWgQuickConfig: config, called: name) - } - if let oldConfig = providerConfiguration?["WgQuickConfig"] as? String { - return try? TunnelConfiguration(fromWgQuickConfig: oldConfig, called: name) - } - return nil - } - - func destroyConfigurationReference() { - guard let ref = passwordReference else { return } - Keychain.deleteReference(called: ref) - } - - func verifyConfigurationReference() -> Bool { - guard let ref = passwordReference else { return false } - return Keychain.verifyReference(called: ref) - } - - @discardableResult - func migrateConfigurationIfNeeded(called name: String) -> Bool { - /* This is how we did things before we switched to putting items - * in the keychain. But it's still useful to keep the migration - * around so that .mobileconfig files are easier. - */ - if let oldConfig = providerConfiguration?["WgQuickConfig"] as? String { - #if os(macOS) - providerConfiguration = ["UID": getuid()] - #elseif os(iOS) - providerConfiguration = nil - #else - #error("Unimplemented") - #endif - guard passwordReference == nil else { return true } - wg_log(.debug, message: "Migrating tunnel configuration '\(name)'") - passwordReference = Keychain.makeReference(containing: oldConfig, called: name) - return true - } - #if os(macOS) - if passwordReference != nil && providerConfiguration?["UID"] == nil && verifyConfigurationReference() { - providerConfiguration = ["UID": getuid()] - return true - } - #endif - return false - } -} diff --git a/WireGuard/Shared/Model/PeerConfiguration.swift b/WireGuard/Shared/Model/PeerConfiguration.swift deleted file mode 100644 index 7fd3f87..0000000 --- a/WireGuard/Shared/Model/PeerConfiguration.swift +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import Foundation - -struct PeerConfiguration { - var publicKey: Data - var preSharedKey: Data? { - didSet(value) { - if let value = value { - if value.count != TunnelConfiguration.keyLength { - fatalError("Invalid preshared key") - } - } - } - } - var allowedIPs = [IPAddressRange]() - var endpoint: Endpoint? - var persistentKeepAlive: UInt16? - var rxBytes: UInt64? - var txBytes: UInt64? - var lastHandshakeTime: Date? - - init(publicKey: Data) { - self.publicKey = publicKey - if publicKey.count != TunnelConfiguration.keyLength { - fatalError("Invalid public key") - } - } -} - -extension PeerConfiguration: Equatable { - static func == (lhs: PeerConfiguration, rhs: PeerConfiguration) -> Bool { - return lhs.publicKey == rhs.publicKey && - lhs.preSharedKey == rhs.preSharedKey && - Set(lhs.allowedIPs) == Set(rhs.allowedIPs) && - lhs.endpoint == rhs.endpoint && - lhs.persistentKeepAlive == rhs.persistentKeepAlive - } -} - -extension PeerConfiguration: Hashable { - func hash(into hasher: inout Hasher) { - hasher.combine(publicKey) - hasher.combine(preSharedKey) - hasher.combine(Set(allowedIPs)) - hasher.combine(endpoint) - hasher.combine(persistentKeepAlive) - - } -} diff --git a/WireGuard/Shared/Model/String+ArrayConversion.swift b/WireGuard/Shared/Model/String+ArrayConversion.swift deleted file mode 100644 index 7d00be9..0000000 --- a/WireGuard/Shared/Model/String+ArrayConversion.swift +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import Foundation - -extension String { - - func splitToArray(separator: Character = ",", trimmingCharacters: CharacterSet? = nil) -> [String] { - return split(separator: separator) - .map { - if let charSet = trimmingCharacters { - return $0.trimmingCharacters(in: charSet) - } else { - return String($0) - } - } - } - -} - -extension Optional where Wrapped == String { - - func splitToArray(separator: Character = ",", trimmingCharacters: CharacterSet? = nil) -> [String] { - switch self { - case .none: - return [] - case .some(let wrapped): - return wrapped.splitToArray(separator: separator, trimmingCharacters: trimmingCharacters) - } - } - -} diff --git a/WireGuard/Shared/Model/TunnelConfiguration+WgQuickConfig.swift b/WireGuard/Shared/Model/TunnelConfiguration+WgQuickConfig.swift deleted file mode 100644 index 5e8f969..0000000 --- a/WireGuard/Shared/Model/TunnelConfiguration+WgQuickConfig.swift +++ /dev/null @@ -1,251 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import Foundation - -extension TunnelConfiguration { - - enum ParserState { - case inInterfaceSection - case inPeerSection - case notInASection - } - - enum ParseError: Error { - case invalidLine(String.SubSequence) - case noInterface - case multipleInterfaces - case interfaceHasNoPrivateKey - case interfaceHasInvalidPrivateKey(String) - case interfaceHasInvalidListenPort(String) - case interfaceHasInvalidAddress(String) - case interfaceHasInvalidDNS(String) - case interfaceHasInvalidMTU(String) - case interfaceHasUnrecognizedKey(String) - case peerHasNoPublicKey - case peerHasInvalidPublicKey(String) - case peerHasInvalidPreSharedKey(String) - case peerHasInvalidAllowedIP(String) - case peerHasInvalidEndpoint(String) - case peerHasInvalidPersistentKeepAlive(String) - case peerHasInvalidTransferBytes(String) - case peerHasInvalidLastHandshakeTime(String) - case peerHasUnrecognizedKey(String) - case multiplePeersWithSamePublicKey - case multipleEntriesForKey(String) - } - - convenience init(fromWgQuickConfig wgQuickConfig: String, called name: String? = nil) throws { - var interfaceConfiguration: InterfaceConfiguration? - var peerConfigurations = [PeerConfiguration]() - - let lines = wgQuickConfig.split { $0.isNewline } - - var parserState = ParserState.notInASection - var attributes = [String: String]() - - for (lineIndex, line) in lines.enumerated() { - var trimmedLine: String - if let commentRange = line.range(of: "#") { - trimmedLine = String(line[..<commentRange.lowerBound]) - } else { - trimmedLine = String(line) - } - - trimmedLine = trimmedLine.trimmingCharacters(in: .whitespacesAndNewlines) - let lowercasedLine = trimmedLine.lowercased() - - if !trimmedLine.isEmpty { - if let equalsIndex = trimmedLine.firstIndex(of: "=") { - // Line contains an attribute - let keyWithCase = trimmedLine[..<equalsIndex].trimmingCharacters(in: .whitespacesAndNewlines) - let key = keyWithCase.lowercased() - let value = trimmedLine[trimmedLine.index(equalsIndex, offsetBy: 1)...].trimmingCharacters(in: .whitespacesAndNewlines) - let keysWithMultipleEntriesAllowed: Set<String> = ["address", "allowedips", "dns"] - if let presentValue = attributes[key] { - if keysWithMultipleEntriesAllowed.contains(key) { - attributes[key] = presentValue + "," + value - } else { - throw ParseError.multipleEntriesForKey(keyWithCase) - } - } else { - attributes[key] = value - } - let interfaceSectionKeys: Set<String> = ["privatekey", "listenport", "address", "dns", "mtu"] - let peerSectionKeys: Set<String> = ["publickey", "presharedkey", "allowedips", "endpoint", "persistentkeepalive"] - if parserState == .inInterfaceSection { - guard interfaceSectionKeys.contains(key) else { - throw ParseError.interfaceHasUnrecognizedKey(keyWithCase) - } - } else if parserState == .inPeerSection { - guard peerSectionKeys.contains(key) else { - throw ParseError.peerHasUnrecognizedKey(keyWithCase) - } - } - } else if lowercasedLine != "[interface]" && lowercasedLine != "[peer]" { - throw ParseError.invalidLine(line) - } - } - - let isLastLine = lineIndex == lines.count - 1 - - if isLastLine || lowercasedLine == "[interface]" || lowercasedLine == "[peer]" { - // Previous section has ended; process the attributes collected so far - if parserState == .inInterfaceSection { - let interface = try TunnelConfiguration.collate(interfaceAttributes: attributes) - guard interfaceConfiguration == nil else { throw ParseError.multipleInterfaces } - interfaceConfiguration = interface - } else if parserState == .inPeerSection { - let peer = try TunnelConfiguration.collate(peerAttributes: attributes) - peerConfigurations.append(peer) - } - } - - if lowercasedLine == "[interface]" { - parserState = .inInterfaceSection - attributes.removeAll() - } else if lowercasedLine == "[peer]" { - parserState = .inPeerSection - attributes.removeAll() - } - } - - let peerPublicKeysArray = peerConfigurations.map { $0.publicKey } - let peerPublicKeysSet = Set<Data>(peerPublicKeysArray) - if peerPublicKeysArray.count != peerPublicKeysSet.count { - throw ParseError.multiplePeersWithSamePublicKey - } - - if let interfaceConfiguration = interfaceConfiguration { - self.init(name: name, interface: interfaceConfiguration, peers: peerConfigurations) - } else { - throw ParseError.noInterface - } - } - - func asWgQuickConfig() -> String { - var output = "[Interface]\n" - if let privateKey = interface.privateKey.base64Key() { - output.append("PrivateKey = \(privateKey)\n") - } - if let listenPort = interface.listenPort { - output.append("ListenPort = \(listenPort)\n") - } - if !interface.addresses.isEmpty { - let addressString = interface.addresses.map { $0.stringRepresentation }.joined(separator: ", ") - output.append("Address = \(addressString)\n") - } - if !interface.dns.isEmpty { - let dnsString = interface.dns.map { $0.stringRepresentation }.joined(separator: ", ") - output.append("DNS = \(dnsString)\n") - } - if let mtu = interface.mtu { - output.append("MTU = \(mtu)\n") - } - - for peer in peers { - output.append("\n[Peer]\n") - if let publicKey = peer.publicKey.base64Key() { - output.append("PublicKey = \(publicKey)\n") - } - if let preSharedKey = peer.preSharedKey?.base64Key() { - output.append("PresharedKey = \(preSharedKey)\n") - } - if !peer.allowedIPs.isEmpty { - let allowedIPsString = peer.allowedIPs.map { $0.stringRepresentation }.joined(separator: ", ") - output.append("AllowedIPs = \(allowedIPsString)\n") - } - if let endpoint = peer.endpoint { - output.append("Endpoint = \(endpoint.stringRepresentation)\n") - } - if let persistentKeepAlive = peer.persistentKeepAlive { - output.append("PersistentKeepalive = \(persistentKeepAlive)\n") - } - } - - return output - } - - private static func collate(interfaceAttributes attributes: [String: String]) throws -> InterfaceConfiguration { - guard let privateKeyString = attributes["privatekey"] else { - throw ParseError.interfaceHasNoPrivateKey - } - guard let privateKey = Data(base64Key: privateKeyString), privateKey.count == TunnelConfiguration.keyLength else { - throw ParseError.interfaceHasInvalidPrivateKey(privateKeyString) - } - var interface = InterfaceConfiguration(privateKey: privateKey) - if let listenPortString = attributes["listenport"] { - guard let listenPort = UInt16(listenPortString) else { - throw ParseError.interfaceHasInvalidListenPort(listenPortString) - } - interface.listenPort = listenPort - } - if let addressesString = attributes["address"] { - var addresses = [IPAddressRange]() - for addressString in addressesString.splitToArray(trimmingCharacters: .whitespacesAndNewlines) { - guard let address = IPAddressRange(from: addressString) else { - throw ParseError.interfaceHasInvalidAddress(addressString) - } - addresses.append(address) - } - interface.addresses = addresses - } - if let dnsString = attributes["dns"] { - var dnsServers = [DNSServer]() - for dnsServerString in dnsString.splitToArray(trimmingCharacters: .whitespacesAndNewlines) { - guard let dnsServer = DNSServer(from: dnsServerString) else { - throw ParseError.interfaceHasInvalidDNS(dnsServerString) - } - dnsServers.append(dnsServer) - } - interface.dns = dnsServers - } - if let mtuString = attributes["mtu"] { - guard let mtu = UInt16(mtuString) else { - throw ParseError.interfaceHasInvalidMTU(mtuString) - } - interface.mtu = mtu - } - return interface - } - - private static func collate(peerAttributes attributes: [String: String]) throws -> PeerConfiguration { - guard let publicKeyString = attributes["publickey"] else { - throw ParseError.peerHasNoPublicKey - } - guard let publicKey = Data(base64Key: publicKeyString), publicKey.count == TunnelConfiguration.keyLength else { - throw ParseError.peerHasInvalidPublicKey(publicKeyString) - } - var peer = PeerConfiguration(publicKey: publicKey) - if let preSharedKeyString = attributes["presharedkey"] { - guard let preSharedKey = Data(base64Key: preSharedKeyString), preSharedKey.count == TunnelConfiguration.keyLength else { - throw ParseError.peerHasInvalidPreSharedKey(preSharedKeyString) - } - peer.preSharedKey = preSharedKey - } - if let allowedIPsString = attributes["allowedips"] { - var allowedIPs = [IPAddressRange]() - for allowedIPString in allowedIPsString.splitToArray(trimmingCharacters: .whitespacesAndNewlines) { - guard let allowedIP = IPAddressRange(from: allowedIPString) else { - throw ParseError.peerHasInvalidAllowedIP(allowedIPString) - } - allowedIPs.append(allowedIP) - } - peer.allowedIPs = allowedIPs - } - if let endpointString = attributes["endpoint"] { - guard let endpoint = Endpoint(from: endpointString) else { - throw ParseError.peerHasInvalidEndpoint(endpointString) - } - peer.endpoint = endpoint - } - if let persistentKeepAliveString = attributes["persistentkeepalive"] { - guard let persistentKeepAlive = UInt16(persistentKeepAliveString) else { - throw ParseError.peerHasInvalidPersistentKeepAlive(persistentKeepAliveString) - } - peer.persistentKeepAlive = persistentKeepAlive - } - return peer - } - -} diff --git a/WireGuard/Shared/Model/TunnelConfiguration.swift b/WireGuard/Shared/Model/TunnelConfiguration.swift deleted file mode 100644 index 5a8f7df..0000000 --- a/WireGuard/Shared/Model/TunnelConfiguration.swift +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. - -import Foundation - -final class TunnelConfiguration { - var name: String? - var interface: InterfaceConfiguration - let peers: [PeerConfiguration] - - static let keyLength = 32 - - init(name: String?, interface: InterfaceConfiguration, peers: [PeerConfiguration]) { - self.interface = interface - self.peers = peers - self.name = name - - let peerPublicKeysArray = peers.map { $0.publicKey } - let peerPublicKeysSet = Set<Data>(peerPublicKeysArray) - if peerPublicKeysArray.count != peerPublicKeysSet.count { - fatalError("Two or more peers cannot have the same public key") - } - } -} - -extension TunnelConfiguration: Equatable { - static func == (lhs: TunnelConfiguration, rhs: TunnelConfiguration) -> Bool { - return lhs.name == rhs.name && - lhs.interface == rhs.interface && - Set(lhs.peers) == Set(rhs.peers) - } -} diff --git a/WireGuard/Shared/Model/key.c b/WireGuard/Shared/Model/key.c deleted file mode 100644 index 6c64443..0000000 --- a/WireGuard/Shared/Model/key.c +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. - * - * This is a specialized constant-time base64/hex implementation that resists side-channel attacks. - */ - -#include <string.h> -#include "key.h" - -static inline void encode_base64(char dest[static 4], const uint8_t src[static 3]) -{ - const uint8_t input[] = { (src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63 }; - - for (unsigned int i = 0; i < 4; ++i) - dest[i] = input[i] + 'A' - + (((25 - input[i]) >> 8) & 6) - - (((51 - input[i]) >> 8) & 75) - - (((61 - input[i]) >> 8) & 15) - + (((62 - input[i]) >> 8) & 3); - -} - -void key_to_base64(char base64[static WG_KEY_LEN_BASE64], const uint8_t key[static WG_KEY_LEN]) -{ - unsigned int i; - - for (i = 0; i < WG_KEY_LEN / 3; ++i) - encode_base64(&base64[i * 4], &key[i * 3]); - encode_base64(&base64[i * 4], (const uint8_t[]){ key[i * 3 + 0], key[i * 3 + 1], 0 }); - base64[WG_KEY_LEN_BASE64 - 2] = '='; - base64[WG_KEY_LEN_BASE64 - 1] = '\0'; -} - -static inline int decode_base64(const char src[static 4]) -{ - int val = 0; - - for (unsigned int i = 0; i < 4; ++i) - val |= (-1 - + ((((('A' - 1) - src[i]) & (src[i] - ('Z' + 1))) >> 8) & (src[i] - 64)) - + ((((('a' - 1) - src[i]) & (src[i] - ('z' + 1))) >> 8) & (src[i] - 70)) - + ((((('0' - 1) - src[i]) & (src[i] - ('9' + 1))) >> 8) & (src[i] + 5)) - + ((((('+' - 1) - src[i]) & (src[i] - ('+' + 1))) >> 8) & 63) - + ((((('/' - 1) - src[i]) & (src[i] - ('/' + 1))) >> 8) & 64) - ) << (18 - 6 * i); - return val; -} - -bool key_from_base64(uint8_t key[static WG_KEY_LEN], const char *base64) -{ - unsigned int i; - volatile uint8_t ret = 0; - int val; - - if (strlen(base64) != WG_KEY_LEN_BASE64 - 1 || base64[WG_KEY_LEN_BASE64 - 2] != '=') - return false; - - for (i = 0; i < WG_KEY_LEN / 3; ++i) { - val = decode_base64(&base64[i * 4]); - ret |= (uint32_t)val >> 31; - key[i * 3 + 0] = (val >> 16) & 0xff; - key[i * 3 + 1] = (val >> 8) & 0xff; - key[i * 3 + 2] = val & 0xff; - } - val = decode_base64((const char[]){ base64[i * 4 + 0], base64[i * 4 + 1], base64[i * 4 + 2], 'A' }); - ret |= ((uint32_t)val >> 31) | (val & 0xff); - key[i * 3 + 0] = (val >> 16) & 0xff; - key[i * 3 + 1] = (val >> 8) & 0xff; - - return 1 & ((ret - 1) >> 8); -} - -void key_to_hex(char hex[static WG_KEY_LEN_HEX], const uint8_t key[static WG_KEY_LEN]) -{ - unsigned int i; - - for (i = 0; i < WG_KEY_LEN; ++i) { - hex[i * 2] = 87U + (key[i] >> 4) + ((((key[i] >> 4) - 10U) >> 8) & ~38U); - hex[i * 2 + 1] = 87U + (key[i] & 0xf) + ((((key[i] & 0xf) - 10U) >> 8) & ~38U); - } - hex[i * 2] = '\0'; -} - -bool key_from_hex(uint8_t key[static WG_KEY_LEN], const char *hex) -{ - uint8_t c, c_acc, c_alpha0, c_alpha, c_num0, c_num, c_val; - volatile uint8_t ret = 0; - - if (strlen(hex) != WG_KEY_LEN_HEX - 1) - return false; - - for (unsigned int i = 0; i < WG_KEY_LEN_HEX - 1; i += 2) { - c = (uint8_t)hex[i]; - c_num = c ^ 48U; - c_num0 = (c_num - 10U) >> 8; - c_alpha = (c & ~32U) - 55U; - c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8; - ret |= ((c_num0 | c_alpha0) - 1) >> 8; - c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha); - c_acc = c_val * 16U; - - c = (uint8_t)hex[i + 1]; - c_num = c ^ 48U; - c_num0 = (c_num - 10U) >> 8; - c_alpha = (c & ~32U) - 55U; - c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8; - ret |= ((c_num0 | c_alpha0) - 1) >> 8; - c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha); - key[i / 2] = c_acc | c_val; - } - - return 1 & ((ret - 1) >> 8); -} diff --git a/WireGuard/Shared/Model/key.h b/WireGuard/Shared/Model/key.h deleted file mode 100644 index bd22a94..0000000 --- a/WireGuard/Shared/Model/key.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. - */ - -#ifndef KEY_H -#define KEY_H - -#include <stdbool.h> -#include <stdint.h> - -#define WG_KEY_LEN (32) -#define WG_KEY_LEN_BASE64 (45) -#define WG_KEY_LEN_HEX (65) - -void key_to_base64(char base64[static WG_KEY_LEN_BASE64], const uint8_t key[static WG_KEY_LEN]); -bool key_from_base64(uint8_t key[static WG_KEY_LEN], const char *base64); - -void key_to_hex(char hex[static WG_KEY_LEN_HEX], const uint8_t key[static WG_KEY_LEN]); -bool key_from_hex(uint8_t key[static WG_KEY_LEN], const char *hex); - -#endif |