Network connections send and receive data using transport and security protocols.

Network Documentation

Pinned Posts

Posts under Network tag

338 Posts
Sort by:
Post not yet marked as solved
0 Replies
4.2k Views
Questions about FTP crop up from time-to-time here on DevForums. In most cases I write a general “don’t use FTP” response, but I don’t have time to go into all the details. I’ve created this post as a place to collect all of those details, so I can reference them in other threads. IMPORTANT Apple’s official position on FTP is: All our FTP APIs have been deprecated, and you should avoid using deprecated APIs. Apple has been slowly removing FTP support from the user-facing parts of our system. The most recent example of this is that we removed the ftp command-line tool in macOS 10.13. You should avoid the FTP protocol and look to adopt more modern alternatives. The rest of this post is an informational explanation of the overall FTP picture. This post is locked so I can keep it focused. If you have questions or comments, please do create a new thread with the Network tag and I’ll respond there. Don’t Use FTP FTP is a very old and very crufty protocol. Certain things that seem obvious to us now — like being able to create a GUI client that reliably shows a directory listing in a platform-independent manner — are not possible to do in FTP. However, by far the biggest problem with FTP is that it provides no security [1]. Specifically, the FTP protocol: Provides no on-the-wire privacy, so anyone can see the data you transfer Provides no client-authenticates-server authentication, so you have no idea whether you’re talking to the right server Provides no data integrity, allowing an attacker to munge your data in transit Transfers user names and passwords in the clear Using FTP for anonymous downloads may be acceptable (see the note below) but most other uses of FTP are completely inappropriate for the modern Internet. IMPORTANT You should only use FTP for anonymous downloads if you have an independent way to check the integrity of the data you’ve downloaded. For example, if you’re downloading a software update, you could use code signing to check its integrity. If you don’t check the integrity of the data you’ve downloaded, an attacker could substitute a malicious download instead. This would be especially bad in, say, the software update case. These fundamental problems with the FTP protocol mean that it’s not a priority for Apple. This is reflected in the available APIs, which is the subject of the next section. FTP APIs Apple provides two FTP APIs: All Apple platforms provide FTP downloads via NSURLSession Most Apple platforms (everything except watchOS) support CFFTPStream, which allows for directory listings, downloads, uploads, and directory creation. All of these FTP APIs are now deprecated: NSURLSession was deprecated for the purposes of FTP in the 2022 SDKs (macOS 13, {i{,Pad},tv}OS 16, watchOS 9) [2]. CFFTPStream was deprecated in the 2016 SDKs (macOS 10.11, {i{,Pad},tv}OS 9). CFFTPStream still works about as well as it ever did, which is not particularly well. Specifically: There is at least one known crashing bug (r. 35745763), albeit one that occurs quite infrequently. There are clear implementation limitations — like the fact that CFFTPCreateParsedResourceListing assumes a MacRoman text encoding (r. 7420589) — that will not be fixed. If you’re looking for an example of how to use these APIs, check out SimpleFTPSample. Note This sample has not been updated since 2013 and is unlikely to ever be updated given Apple’s position on FTP. The FTP support in NSURLSession has significant limitations: NSURLSession only supports FTP downloads; there is no support for uploads or any other FTP operations NSURLSession does not support resumable FTP downloads [3] NSURLSession background sessions only support HTTP and HTTPS, so you can’t run FTP downloads in the background on iOS If Apple’s FTP APIs are insufficient for your needs, you’ll need to write or acquire your own FTP library. Before you do that, however, consider switching to an alternative protocol. After all, if you’re going to go to the trouble of importing a large FTP library into your code base, you might as well import a library for a better protocol. The next section discusses some options in this space. Alternative Protocols There are numerous better alternatives to FTP: HTTPS is by far the best alternative to FTP, offering good security, good APIs on Apple platforms, good server support, and good network compatibility. Implementing traditional FTP operations over HTTPS can be a bit tricky. One possible way forward is to enable DAV extensions on the server. FTPS is FTP over TLS (aka SSL). While FTPS adds security to the protocol, which is very important, it still inherits many of FTP’s other problems. Personally I try to avoid this protocol. SFTP is a file transfer protocol that’s completely unrelated to FTP. It runs over SSH, making it a great alternative in many of the ad hoc setups that traditionally use FTP. Apple does not have an API for either FTPS or SFTP, although on macOS you may be able to make some headway by invoking the sftp command-line tool. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" [1] In another thread someone asked me about FTP’s other problems, those not related to security, so let’s talk about that. One of FTP’s implicit design goals was to provide cross-platform support that exposes the target platform. You can think of FTP as being kinda like telnet. When you telnet from Unix to VMS, it doesn’t aim to abstract away VMS commands, so that you can type Unix commands at the VMS prompt. Rather, you’re expected to run VMS commands. FTP is (a bit) like that. This choice made sense back when the FTP protocol was invented. Folks were expecting to use FTP via a command-line client, so there was a human in the loop. If they ran a command and it produced VMS-like output, that was fine because they knew that they were FTPing into a VMS machine. However, most users today are using GUI clients, and this design choice makes it very hard to create a general GUI client for FTP. Let’s consider the simple problem of getting the contents of a directory. When you send an FTP LIST command, the server would historically run the platform native directory list command and pipe the results back to you. To create a GUI client you have to parse that data to extract the file names. Doing that is a serious challenge. Indeed, just the first step, working out the text encoding, is a challenge. Many FTP servers use UTF-8, but some use ISO-Latin-1, some use other standard encodings, some use Windows code pages, and so on. I say “historically” above because there have been various efforts to standardise this stuff, both in the RFCs and in individual server implementations. However, if you’re building a general client you can’t rely on these efforts. After all, the reason why folks continue to use FTP is because of it widespread support. [2] To quote the macOS 13 Ventura Release Notes: FTP is deprecated for URLSession and related APIs. Please adopt modern secure networking protocols such as HTTPS. (92623659) [3] Although you can implement resumable downloads using the lower-level CFFTPStream API, courtesy of the kCFStreamPropertyFTPFileTransferOffset property. Revision History 2024-04-15 Added a footnote about FTP’s other problems. Made other minor editorial changes. 2022-08-09 Noted that the FTP support in NSURLSession is now deprecated. Made other minor editorial changes. 2021-04-06 Fixed the formatting. Fixed some links. 2018-02-23 First posted.
Posted
by eskimo.
Last updated
.
Post marked as solved
3 Replies
283 Views
Issue When using the nio-ssh library to execute ssh commands in a daemonized context (built executable launched using launchctl with a config in /Library/LaunchDaemons) a ChannelError (operationUnsupported) is thrown. I'm unsure if this is a problem just with nio-ssh or nio in general. Could it be that certain network operations aren't permitted from within a daemon? Any information/help on this matter is greatly appreciated! Related issue in the nio-ssh repository: https://github.com/apple/swift-nio-ssh/issues/166 Unfortunately there are no specific tags for these libraries (nio, nio-ssh) or for daemons, so I have used the Network tag instead. Reproduction Reproduction can be found here: https://github.com/eliaSchenker/nio-ssh-daemon-issue/tree/main To run the reproduction follow these steps: Build using Xcode (Product > Build) Find the executable in the build folder (Product > Show Build Folder in Finder) Move the executable to /Library/PrivilegedHelperTools Create a daemon configuration in /Library/LaunchDaemons/nio-ssh-daemon.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>nio-ssh-daemon</string> <key>ProgramArguments</key> <array> <string>/Library/PrivilegedHelperTools/nio-ssh-daemon</string> <string>username:password@host</string> <string>ls -la</string> </array> <key>KeepAlive</key> <true/> <key>ProcessType</key> <string>Interactive</string> <key>StandardOutPath</key> <string>/Library/Logs/nio-ssh-daemon.out.log</string> <key>StandardErrorPath</key> <string>/Library/Logs/nio-ssh-daemon.err.log</string> </dict> </plist> making sure to adjust the program arguments to include an host with username and password. Load the daemon using sudo launchctl load nio-ssh-daemon.plist When opening Console.app, navigating to Log Reports and opening nio-ssh-daemon.out.log the logged error will be shown: Creating bootstrap Connecting channel Creating child channel Waiting for connection to close Error in pipeline: operationUnsupported An error occurred: commandExecFailed If the executable is run manually without a daemon it will work correctly: ./nio.ssh-daemon username:password@host The reproduction is a copy of the example in the repository (https://github.com/apple/swift-nio-ssh/tree/main/Sources/NIOSSHClient) with slight modifications to log errors instead of using try!.
Posted
by Elia314.
Last updated
.
Post marked as solved
1 Replies
328 Views
I'm following the approach in https://developer.apple.com/forums/thread/703234 section "Doing Even Better: Proper Security". My question is: does it work if the accessory is not in the local network (i.e. out there on the Internet with an IP address) ? I tried and: SecTrustEvaluateWithError(trust, nil) returns true, but TLS still fails: ATS failed system trust Connection 1: system TLS Trust evaluation failed(-9802) <snip> Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, Here is my code : var err = SecTrustSetPolicies(trust, SecPolicyCreateBasicX509()) os_log("SecTrustSetPolicies returns \(err)") err = SecTrustSetAnchorCertificates(trust, [self.myCA] as NSArray) os_log("SecTrustSetAnchorCertificates returns \(err)") err = SecTrustSetAnchorCertificatesOnly(trust, true) os_log("SecTrustSetAnchorCertificatesOnly returns \(err)") // check the trust object let evalResult = SecTrustEvaluateWithError(trust, nil) os_log("SecTrust eval result: \(evalResult)") // create a credential with accepted server trust. let credential = URLCredential(trust: trust) completionHandler(.useCredential, credential) the logs are: SecTrustSetPolicies returns 0 SecTrustSetAnchorCertificates returns 0 SecTrustSetAnchorCertificatesOnly returns 0 SecTrust eval result: true Did I do anything wrong? or is it not supported outside the local network? Thanks.
Posted Last updated
.
Post not yet marked as solved
3 Replies
305 Views
I am trying to set up a secure local websocket server on a mac using swift. I think I am able to get a non-secure server running (still untested). But I am unable to find any documentation that points to how to set up a secure connection (say uses TLS 1.2) if I have an ssl cert, an intermediate cert (both pem files) and the private key for that cert. Any insight would be great. Any code samples that show setting up a local secure websocket server that makes use of certificates and private keys would be even better.
Posted
by skdexcom.
Last updated
.
Post not yet marked as solved
3 Replies
346 Views
Hello, context : 2 Institutions being part of the eduroam Federation : they both offer the ssid eduroam the 2 institutions are physically closed to each other (on the same campus) A client from Institution_A authenticate 802.1x to ssid eduroam of its institution : after successfull authentication, the client gets a new ip address from the dhcp server of Institution_A The same client walks towards Institution_B : the client associate with ssid eduroam of Institution_B the client authenticate through the federation against its Institution_A authentication server after successfull authentication, the client starts the process of getting an ip address At that point here is what is observed on all iPhone/iPad : the client asks for its previously obtanined ip address from Institution_A (DHCPREQUEST) the dhcp server of Institution_B issues a DHCPNAK to the client because the ip address asked is not part of its subnets the client continuosly repeat the process of asking its former ip address, the process can last for minutes/hours (maybe till the end of lease ?) As a result the client has no wifi working, till the client decide to issue a DHCPDISCOVER and then get a valid new ip address Even after a shutdown, the client keeps on asking the same ip address (to be confirmed, but so far this what has been seen). It is devastating for all our Apple clients. Regards
Posted
by merkhabha.
Last updated
.
Post not yet marked as solved
1 Replies
275 Views
I am having crash on com.apple.network.connections randomly. I couldn't reproduce in my local, but I keep seen in my Firebase. Thanks in advance. stacktrace_0.txt stacktrace_1.txt
Posted
by 1729k.
Last updated
.
Post not yet marked as solved
1 Replies
455 Views
Hi there, I think I may have caught a bug in the iOS system. Please confirm. Problem Newly installed Watch-Only and Independent apps on the Apple Watch do not have a network connection when paired with an iPhone until the iPhone is rebooted. Please see the attached screenshot; the iPhone indicates 'WiFi and Cellular policy: kDeny'. Use Case For our end-users, they will install the Watch-Only app directly from the App Store on the Apple Watch, and of course, their watch is paired with their iPhone. In this case, the Watch-Only app has no network connection at all after installation. The user has to reboot the iPhone once, and then the Watch-Only app can access the network. It is unacceptable for the end-users. System Info WatchOS: 10.1.1 Watch Model: A2770, Apple Watch Series 8 (GPS only) iOS Version: 17.4.1 iPhone Model: iPhone 15 XCode: 15.3 How to reproduce Please download the very simple sample code attached. It features the official URLSession Demo Code, which initiates a default URLSession to access https://www.example.com. ContentView.swift Prepare an iPhone and an Apple Watch, then connect the watch to the iPhone and ensure they are paired correctly. Ensure that your iPhone properly connects to a working WiFi network. Now, connect both your Apple Watch and iPhone to Xcode and run the code on the watch. Xcode will then install the Watch-Only app on your watch. After installation, click the 'Click' button on the watch app, and you will receive an error message stating 'The Internet connection appears to be offline...' Now, check the Console output of your iPhone and filter by 'wifi policy'. You will see logs stating 'Adding CU Policy: Bundle IDs: (the-bundle-id) Wifi policy: kDeny Cellular policy: kDeny'. Now, reboot your iPhone and wait for it to reconnect to the WiFi network. Check the Control Center on your watch to ensure the little green iPhone icon is displayed, indicating that your watch is now paired correctly with the iPhone. Click the 'Click' button again on the watch app, and this time it will work perfectly. To repeat the process, simply uninstall the watch app from your watch, and run the sample code again. Xcode will reinstall the app onto the watch. This time, the app will not work until you reboot the iPhone again. References Proxy Through iPhone https://developer.apple.com/documentation/watchos-apps/keeping-your-watchos-app-s-content-up-to-date#Test-your-update-code-with-different-configurations Sample Code struct ContentView: View { @State var txt = "Hello World!" var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text(txt) Button("Click") { startLoad() } }.padding() } func startLoad() { let config = URLSessionConfiguration.default config.waitsForConnectivity = false config.allowsCellularAccess = true config.allowsExpensiveNetworkAccess = true config.allowsConstrainedNetworkAccess = true let sesh = URLSession(configuration: config) let url = URL(string: "https://www.example.com")! sesh.dataTask(with: url) { data, response, error in if let error = error { self.txt = error.localizedDescription // self.handleClientError(error) return } guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { self.txt = response.debugDescription // self.handleServerError(response) return } if let mimeType = httpResponse.mimeType, mimeType == "text/html", let data = data, let string = String(data: data, encoding: .utf8) { DispatchQueue.main.async { self.txt = string // self.webView.loadHTMLString(string, baseURL: url) } } }.resume() } } #Preview { ContentView() }
Posted
by BillHoo.
Last updated
.
Post not yet marked as solved
2 Replies
312 Views
Hello, I develop an iOS game with Unreal Engine 5. My game works perfectly well in the Editor on my mac and on Android, but on iOS somehow once the app in installed, it cannot connect to our game server through WebSocket with a wss URL. wss being a secured connection I don't see what the issue is, but it looks like it's being blocked by Apple ? No issue communicating with Rest API with our server thought. I have done that so far : In App ID profile I enabled Custom Networks and Push Notification, set up a SSL certificate. Here is my change in the .plist: <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>MyApp</string> </array> </dict> </array> <key>NSCameraUsageDescription</key> <string>We don't and cannot use the Camera at all but UnrealEngine integrates SDK for games using camera</string> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSAllowsArbitraryLoadsForMedia</key> <true/> <key>NSAllowsArbitraryLoadsInWebContent</key> <true/> <key>NSAllowsLocalNetworking</key> <true/> <key>NSExceptionDomains</key> <dict> <key>myapp.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> <key>NSExceptionRequiresForwardSecrecy</key> <true/> <key>NSRequiresCertificateTransparency</key> <true/> </dict> </dict> </dict> Thanks in advance,
Posted
by MWStudio.
Last updated
.
Post not yet marked as solved
0 Replies
341 Views
We have been using the BGTask (specifically a BGProcessingTask) reliably for the last couple of years for our app. Up until now they wake up automatically while the screen is off, the iPad is plugged in, and the app is running (that is, in the background), but never while the screen is on (that is, never when the scenePhase == .active). For the last month or so, I've noticed that they are triggering now while the screen is displayed. How is this possible??? Did something change with a recent version of iOS? It's violating Apple's own documentation, which describes the BGProcessingTask as: "A time-consuming processing task that runs while the app is in the background."
Posted Last updated
.
Post not yet marked as solved
1 Replies
385 Views
I am encountering an issue while using the SystemConfiguration framework to detect IPv4 address changes and active interfaces on macOS. Specifically, I'm facing difficulties when the interface switches from one network to another. When connected to a network with a Captive Portal enabled, I'm unable to retrieve the active interface using the stored key State:/Network/Global/IPv4. The output I receive is: No such key However, when I attempt to retrieve interface information using scutil --nwi, the output is as follows: IPv4 network interface information No IPv4 states found REACH : flags 0x00000000 (Not Reachable) IPv6 network interface information No IPv6 states found REACH : flags 0x00000000 (Not Reachable) Network interfaces: en0 Despite this output, the interface en0 is active and has a valid IPv4 address: when checking through ifconfig: en0:flags=8b63&lt;UP,BROADCAST,SMART,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST&gt; mtu 1500 options=6460&lt;TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM&gt; ether bc:d0:74:07:2a:33 inet6 fe80::412:ec:40df:4211%en0 prefixlen 64 secured scopeid 0x12 inet 10.42.0.5 netmask 0xffffff00 broadcast 10.42.0.255 nd6 options=201&lt;PERFORMNUD,DAD&gt; media: autoselect status: active It's evident that the interface is active and has a valid IPv4 address, but the retrieval methods using SystemConfiguration framework are not providing the expected output. I'm seeking assistance in resolving this discrepancy and accurately detecting active interfaces on macOS. Any insights or suggestions would be greatly appreciated. Thank you.
Posted
by jainash.
Last updated
.
Post not yet marked as solved
0 Replies
384 Views
I'm wondering if there's a way to capture the SSL/TLS key log / ephemeral keys from Safari for troubleshooting like there is for Firefox & Chrome by setting the SSLKEYLOGFILE environment variable. I'm troubleshooting an issue where Safari doesn't load certain CSS and JPEG elements on the first load, but when hitting refresh, those same elements load fine. Clearing the cache or using "disable caches" in the network tab of the inspector will cause the elements to fail to load again. Safari shows that it received a header, but no content. Wireshark shows four TCP/RST packets coming from the client / Safari. The same site loads without issue every time using Firefox or Chromium. I'm hoping that someone knows how to capture the TLS session keys from Safari so I can look deeper into the packet capture and figure out if Safari is incorrectly parsing the server's response or if there is some subtle corruption in the response that Safari rejects, but other browsers accept. So, does anyone know how to capture the raw data transfer or TLS session keys from Safari? Thank you!
Posted Last updated
.
Post not yet marked as solved
2 Replies
266 Views
I'm creating an app that uses broadcasts using sockets. But there's something strange about it. It is possible to send packets from other platforms like mac and windows and receive them in iOS, but it's impossible to receive packets from iOS in other platforms. iOS -> Other (OK) Other -> iOS (Not OK) If ios app send packet, it can't receive any bytes in other platforms. Communication between iOS devices is no problem, and there is no problem between other platforms too. For example, iPhone apps and iPad apps can communicate, and Macbook and Windows can communicate in the same way. However, iPhone and mac cannot communicate. I use UDP, ipv6, Broadcast, address: ff02::1, port: 14001 What is wrong with sending from the ios to another platform?
Posted
by kimrugi.
Last updated
.
Post not yet marked as solved
1 Replies
291 Views
Why is it normal to use IJKPlayer to play rtsp real-time stream preview black screen when opening mobile traffic on some mobile phones, and cut into flight mode? Whether mobile traffic affects local network access?
Posted
by JsonWuM.
Last updated
.
Post marked as solved
2 Replies
311 Views
Folks, I’m trying (for tests of third party hardware) to set up a very simple ‘UDP parrot’. It receives a packet, and returns it to the source with a '*' prefixed. Can’t get it work. The following code works like a charm on FreeBSD, but won’t work on MacOS: #include &lt;stdio.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/socket.h&gt; #include &lt;netdb.h&gt; #include &lt;arpa/inet.h&gt; #include &lt;unistd.h&gt; #include &lt;sys/errno.h&gt; #include &lt;string.h&gt; int main(int argc, const char * argv[]) { struct sockaddr_in myAddr; struct sockaddr_in rmtAddr; socklen_t rmtAddrLength; char buffer [2048]; char src [256]; printf ("Opening socket…\n"); int sock; if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { printf("Cannot open UDP socket. Bailing!\n"); return -1; } int opt = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &amp;opt, sizeof(opt)); myAddr.sin_family = AF_INET; myAddr.sin_addr.s_addr = INADDR_ANY; myAddr.sin_port = htons(5522); if (bind(sock, (struct sockaddr *) &amp;myAddr, sizeof(myAddr))) { printf ("Error binding socket -&gt; %d\n", errno); return -1; } printf ("Listening…\n"); while (1) { ssize_t dataLength = recvfrom(sock, buffer + 1, sizeof(buffer) - 1, 0, (struct sockaddr *)&amp; rmtAddr, &amp; rmtAddrLength); printf ("Received %zd bytes: %s\n", dataLength, buffer); printf ("addrLength: %d\n", rmtAddrLength); inet_ntop(AF_INET, &amp; rmtAddr.sin_addr, src, sizeof(src)); printf("From %s port %d\n", src, ntohs (rmtAddr.sin_port)); if (! strncmp (buffer + 1, "STOP", 4)) { sendto (sock, "Terminated\n", 11, 0, (struct sockaddr *)&amp; rmtAddr, sizeof(rmtAddr)); break;} buffer [0] = '*'; dataLength = sendto(sock, buffer, dataLength + 1, 0, (struct sockaddr *)&amp; rmtAddr, sizeof(rmtAddr)); } return 0; } The problem is, the rmtAddr structure, which is supposed to contain the IP address of the remote sender, well, does not. I always get 1.0.0.0 instead. As I said before, I have no such problem with the exact same code on FreeBSD. Also, rmtAddrLength, which is 8 on FreeBSD, is 16 on MacOS apparently. I've dumped the memory starting at &amp;rmtAddr and did not see a hint of a possible IP address. Any idea what could be wrong? Thanks ! V.
Posted Last updated
.
Post not yet marked as solved
2 Replies
290 Views
I can't seem to find the answer anywhere online and through vendor support channels. Is it possible to trigger per-app VPN on unmanaged apps by leveraging the safari/browser domain whitelist on a user enrolment type device? According to this document from Apple, it seems like it's possible. https://developer.apple.com/documentation/devicemanagement/applayervpn?changes=latest_minor However it is missing the context as to which enrolment type is available on.
Posted
by ws-roy.
Last updated
.
Post marked as solved
1 Replies
333 Views
Hi everyone, I'm currently working on a project that involves using the Network framework on macOS 10.15 and iOS 12. While implementing error handling for my network connections, I encountered a warning about the conformance of 'NWError' to 'CustomNSError', which is only available in macOS 13.3 or newer. Here's the warning message I received while compiling the code: Warning: conformance of 'NWError' to 'CustomNSError' is only available in macOS 13.3 or newer self.vConnection = try NWConnection (to: self.vBaseSocketProperties!.uEndpoint!, using: self.vBaseSocketProperties!.uParamters!) self.vConnection?.stateUpdateHandler = { connectionState in switch connectionState { case .failed(let err): error_code = err.errorCode //Below all the other cases are also handled. }
Posted Last updated
.
Post not yet marked as solved
0 Replies
6.3k Views
Transport Layer Security (TLS) is the most important security protocol on the Internet today. Most notably, TLS puts the S into HTTPS, adding security to the otherwise insecure HTTP protocol. IMPORTANT TLS is the successor to the Secure Sockets Layer (SSL) protocol. SSL is no longer considered secure and it’s now rarely used in practice, although many folks still say SSL when they mean TLS. TLS is a complex protocol. Much of that complexity is hidden from app developers but there are places where it’s important to understand specific details of the protocol in order to meet your requirements. This post explains the fundamentals of TLS, concentrating on the issues that most often confuse app developers. Note If you’re working on TLS in the local environment, for example, to talk to a Wi-Fi based accessory, see TLS For Accessory Developers. Server Certificates For standard TLS to work the server must have a digital identity, that is, the combination of a certificate and the private key matching the public key embedded in that certificate. TLS Crypto Magic™ ensures that: The client gets a copy of the server’s certificate. The client knows that the server holds the private key matching the public key in that certificate. In a typical TLS handshake the server passes the client a list of certificates, where item 0 is the server’s certificate (the leaf certificate), item N is (optionally) the certificate of the certificate authority that ultimately issued that certificate (the root certificate), and items 1 through N-1 are any intermediate certificates required to build a cryptographic chain of trust from 0 to N. Note The cryptographic chain of trust is established by means of digital signatures. Certificate X in the chain is issued by certificate X+1. The owner of certificate X+1 uses their private key to digitally sign certificate X. The client verifies this signature using the public key embedded in certificate X+1. Eventually this chain terminates in a trusted anchor, that is, a certificate that the client trusts by default. Typically this anchor is a self-signed root certificate from a certificate authority. Note Item N is optional for reasons I’ll explain below. Also, the list of intermediate certificates may be empty (in the case where the root certificate directly issued the leaf certificate) but that’s uncommon for servers in the real world. Once the client gets the server’s certificate, it evaluates trust on that certificate to confirm that it’s talking to the right server. There are three levels of trust evaluation here: Basic X.509 trust evaluation checks that there’s a cryptographic chain of trust from the leaf through the intermediates to a trusted root certificate. The client has a set of trusted root certificates built in (these are from well-known certificate authorities, or CAs), and a site admin can add more via a configuration profile. This step also checks that none of the certificates have expired, and various other more technical criteria (like the Basic Constraints extension). Note This explains why the server does not have to include the root certificate in the list of certificates it passes to the client; the client has to have the root certificate installed if trust evaluation is to succeed. In addition, TLS trust evaluation (per RFC 2818) checks that the DNS name that you connected to matches the DNS name in the certificate. Specifically, the DNS name must be listed in the Subject Alternative Name extension. Note The Subject Alternative Name extension can also contain IP addresses, although that’s a much less well-trodden path. Also, historically it was common to accept DNS names in the Common Name element of the Subject but that is no longer the case on Apple platforms. App Transport Security (ATS) adds its own security checks. Basic X.509 and TLS trust evaluation are done for all TLS connections. ATS is only done on TLS connections made by URLSession and things layered on top URLSession (like WKWebView). In many situations you can override trust evaluation; for details, see Technote 2232 HTTPS Server Trust Evaluation). Such overrides can either tighten or loosen security. For example: You might tighten security by checking that the server certificate was issued by a specific CA. That way, if someone manages to convince a poorly-managed CA to issue them a certificate for your server, you can detect that and fail. You might loosen security by adding your own CA’s root certificate as a trusted anchor. IMPORTANT If you rely on loosened security you have to disable ATS. If you leave ATS enabled, it requires that the default server trust evaluation succeeds regardless of any customisations you do. Mutual TLS The previous section discusses server trust evaluation, which is required for all standard TLS connections. That process describes how the client decides whether to trust the server. Mutual TLS (mTLS) is the opposite of that, that is, it’s the process by which the server decides whether to trust the client. Note mTLS is commonly called client certificate authentication. I avoid that term because of the ongoing confusion between certificates and digital identities. While it’s true that, in mTLS, the server authenticates the client certificate, to set this up on the client you need a digital identity, not a certificate. mTLS authentication is optional. The server must request a certificate from the client and the client may choose to supply one or not (although if the server requests a certificate and the client doesn’t supply one it’s likely that the server will then fail the connection). At the TLS protocol level this works much like it does with the server certificate. For the client to provide this certificate it must apply a digital identity, known as the client identity, to the connection. TLS Crypto Magic™ assures the server that, if it gets a certificate from the client, the client holds the private key associated with that certificate. Where things diverge is in trust evaluation. Trust evaluation of the client certificate is done on the server, and the server uses its own rules to decided whether to trust a specific client certificate. For example: Some servers do basic X.509 trust evaluation and then check that the chain of trust leads to one specific root certificate; that is, a client is trusted if it holds a digital identity whose certificate was issued by a specific CA. Some servers just check the certificate against a list of known trusted client certificates. When the client sends its certificate to the server it actually sends a list of certificates, much as I’ve described above for the server’s certificates. In many cases the client only needs to send item 0, that is, its leaf certificate. That’s because: The server already has the intermediate certificates required to build a chain of trust from that leaf to its root. There’s no point sending the root, as I discussed above in the context of server trust evaluation. However, there are no hard and fast rules here; the server does its client trust evaluation using its own internal logic, and it’s possible that this logic might require the client to present intermediates, or indeed present the root certificate even though it’s typically redundant. If you have problems with this, you’ll have to ask the folks running the server to explain its requirements. Note If you need to send additional certificates to the server, pass them to the certificates parameter of the method you use to create your URLCredential (typically init(identity:certificates:persistence:)). One thing that bears repeating is that trust evaluation of the client certificate is done on the server, not the client. The client doesn’t care whether the client certificate is trusted or not. Rather, it simply passes that certificate the server and it’s up to the server to make that decision. When a server requests a certificate from the client, it may supply a list of acceptable certificate authorities [1]. Safari uses this to filter the list of client identities it presents to the user. If you are building an HTTPS server and find that Safari doesn’t show the expected client identity, make sure you have this configured correctly. If you’re building an iOS app and want to implement a filter like Safari’s, get this list using: The distinguishedNames property, if you’re using URLSession The sec_protocol_metadata_access_distinguished_names routine, if you’re using Network framework [1] See the certificate_authorities field in Section 7.4.4 of RFC 5246, and equivalent features in other TLS versions. Self-Signed Certificates Self-signed certificates are an ongoing source of problems with TLS. There’s only one unequivocally correct place to use a self-signed certificate: the trusted anchor provided by a certificate authority. One place where a self-signed certificate might make sense is in a local environment, that is, securing a connection between peers without any centralised infrastructure. However, depending on the specific circumstances there may be a better option. TLS For Accessory Developers discusses this topic in detail. Finally, it’s common for folks to use self-signed certificates for testing. I’m not a fan of that approach. Rather, I recommend the approach described in QA1948 HTTPS and Test Servers. For advice on how to set that up using just your Mac, see TN2326 Creating Certificates for TLS Testing. TLS Standards RFC 6101 The Secure Sockets Layer (SSL) Protocol Version 3.0 (historic) RFC 2246 The TLS Protocol Version 1.0 RFC 4346 The Transport Layer Security (TLS) Protocol Version 1.1 RFC 5246 The Transport Layer Security (TLS) Protocol Version 1.2 RFC 8446 The Transport Layer Security (TLS) Protocol Version 1.3 RFC 4347 Datagram Transport Layer Security RFC 6347 Datagram Transport Layer Security Version 1.2 RFC 9147 The Datagram Transport Layer Security (DTLS) Protocol Version 1.3 Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Revision History: 2024-03-19 Adopted the term mutual TLS in preference to client certificate authentication throughout, because the latter feeds into the ongoing certificate versus digital identity confusion. Defined the term client identity. Added the Self-Signed Certificates section. Made other minor editorial changes. 2023-02-28 Added an explanation mTLS acceptable certificate authorities. 2022-12-02 Added links to the DTLS RFCs. 2022-08-24 Added links to the TLS RFCs. Made other minor editorial changes. 2022-06-03 Added a link to TLS For Accessory Developers. 2021-02-26 Fixed the formatting. Clarified that ATS only applies to URLSession. Minor editorial changes. 2020-04-17 Updated the discussion of Subject Alternative Name to account for changes in the 2019 OS releases. Minor editorial updates. 2018-10-29 Minor editorial updates. 2016-11-11 First posted.
Posted
by eskimo.
Last updated
.
Post not yet marked as solved
1 Replies
552 Views
With SCNetworkReachabilityCreateWithAddress now depreciated I'm having to use NWPathMonitor to determine if I have a good connection to access some HTML and JSON files. I have this working just fine if the network connection is down but if the network connection comes back up it detects an event but still shows the status as unsatisfied. I can't seem to capture or pickup that when I've got a good connection again so I can proceed with the right status. Here is my current code. Any suggestions would be appreciated: import Network import Combine class NetworkStatus: ObservableObject { static let shared = NetworkStatus() private var monitor: NWPathMonitor? private var queue = DispatchQueue(label: "NetworkMonitor") @Published var isConnected: Bool = false private init() { monitor = NWPathMonitor() startMonitoring() } deinit { stopMonitoring() } func startMonitoring() { monitor?.pathUpdateHandler = { [weak self] path in DispatchQueue.main.async { let status = path.status == .satisfied self?.isConnected = status print(">>> \(path.status)") } } monitor?.start(queue: queue) } func stopMonitoring() { monitor?.cancel() monitor = nil } }
Posted Last updated
.
Post not yet marked as solved
1 Replies
308 Views
I am using UDP communication in a app. Here is what i do, Initialises a UDP broadcast connection object. Bind it with a port to listen Receives the IP &amp; Port from the UDP connection to connect further with TCP connection. After updating Xcode 15.3, It works until the iPad is connected with mac in debug mode. When i create build to test remotely, it stops receiving IP &amp; Port from UDP connection. Here is how i concluded this is Xcode issue, I tried to debug this issue with Xcode 15.2 and it works as expected with debug and after creating build also. Any help / suggestion would be appreciated.
Posted Last updated
.
Post not yet marked as solved
0 Replies
238 Views
Hello fellow developers and Apple support, I'm experiencing a challenging issue with NWConnection when sending data via QUIC udp datagrams to multiple devices. I have a setup where I use NWListener to send data every 10 milliseconds to 10 or even 15 clients, which works flawlessly. However, when I switch to using NWConnection to send data every 20 milliseconds, I encounter significant packet loss, and the following error messages appear in the console: nw_connection_create_with_connection_internal [C19] Original connection not yet connected nw_connection_group_create_connection_for_endpoint_and_parameters [G2] failed to create connection with parameters QUIC, traffic class: 300, local: 0.0.0.0:9000, attribution: developer, attach protocol listener This issue is mitigated when a second NWConnection is connected to the same NWListener, reducing the frequency of errors. By adding a third connection, the errors almost disappear, which suggests that the problem might be related to how a single NWConnection handles rapid data transmissions. This observation leads me to believe that the issue could be linked to the capacity or the management of connections under high throughput scenarios (200kb every 20ms). I've thoroughly reviewed the documentation for NWConnection and NWListener, focusing on their QUIC protocols handling, without finding a clear cause or solution for this issue. I've also searched through forums and developer communities for similar problems but haven't found anything that matches my situation closely. Thank you in advance for your time and help!
Posted
by MinchoPM.
Last updated
.