iOS Secure Transport TLS extensions - ios

I am developing an application that talks to a peer via a secure channel. The data is secured via Apple's Secure Transport Framework. I am actually trying to remove the TLS extensions from the Client Hello message by configuring the SSLContextRef object but the extensions remained.
Is it possible to remove TLS extensions from the Client Hello message that is sent to the server ? If possible then what are the extensions that can be configured ?
Thanks.

I recently created a code package for handling TLS that takes into account the new TLS restrictions imposed by apple for iOS 13. Here is a link:
https://github.com/eamonwhiter73/IOSObjCWebSockets
With how I structure things, the point in the code you want to change is probably here (if you are using Network.h package):
nw_parameters_configure_protocol_block_t configure_tls = NW_PARAMETERS_DISABLE_PROTOCOL;
nw_parameters_t parameters = nw_parameters_create_secure_tcp(
configure_tls,
NW_PARAMETERS_DEFAULT_CONFIGURATION
);
Instead of a long confusing configure_tls block (like in my code), if you want to disable TLS, you can pass NW_PARAMETERS_DISABLE_PROTOCOL in place of where you would pass the configure_tls block (if you were to configure a secure connection). Hope this helps.

Related

Make Web Request in iOS to Web Server that Accepts Client Certificates

I am writing an iOS app that hits one of our own web servers to leverage data. The IIS web server is publicly-accessible, has valid cryptography certificates, and uses TLS 1.2. To my knowledge, all that is up to snuff with App Transport Security. When making web requests in the app, the request times out, but more interestingly, this message is logged "NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9806)".
This IIS server happens to Accept X509 client certificates for a separate use case that does not involve the mobile app. Changing the setting to Ignore results in the iOS app hitting the server fine. I assume the timeout occurs because the server is prompting the app for a client certificate and it doesn't just respond that it doesn't have one. Note, I don't have the client certificates set to Require. I am not sure how to have the iOS app play nicely and just carry on when prompted by the server for a client certificate.
Is there a way to get this to work in iOS while allowing the IIS server to still Accept client certificates? I don't want to diminish ATS by adding hacky exclusions to info.plist.
I don't think it's relevant, but I am developing the iOS app in Xamarin.IOS in C#. A request goes something like this:
using (var client = new WebClient())
{
client.Headers.Add(Constants.RequestHeaders.RequestId, nonce.RequestId.ToString());
client.Headers.Add(Constants.RequestHeaders.Signature, Convert.ToBase64String(nonce.DigitalSignature));
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
var resultJson = client.UploadString("https://foo.com/Api/Register", json);
}
EDIT:
I was able to resolve this issue by using the library ModernHttpClient available via NuGet. The API site accepts client certificates, but does not require them. In most browsers, this results in a one-time prompt by the browser asking you to specify the cert you'd like to use. However, in iOS, making a programmatic web request by default does not bring up a prompt (of course) nor does it inform the server it does not have a cert to provide. Hence, the request simply timed out. With ModernHttpClient, I found a way to set this behavior to automatically resolve.
var handler = new NativeMessageHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
using (var client = new HttpClient(handler))
{ ...
Now it works fine. I'd prefer to not have to include a library just for this very specific purpose, but it works. Perhaps this specific functionality could be distilled into a few lines of code without using the library? Regardless, I'm thankful for ModernHttpClient solving this issue; it's really hacky to change server behavior just to support an iOS quirk.
Can you try change iOS Build setting.
change SSL/TLS implement use * Apple TLS *
change HttpClient implementation use * NSUrlSession *
I had similar problem and using HttpClient to call our public Https API, above setting fixed the issue.

do ios webviews check urls for malware before opening them?

If I open arbitrary urls in my ios application, will I have to do my own malware/phishing/etc... checks? Does the webview (implicitly) do any work on my behalf (or would i have to switch a setting somewhere?)?
In short: no.
UIWebView only has some restricts about javascript same-origin policy, and iOS has it's own SSL Certificates Validation (TLS Chain Validation) which can help UIWebView a little bit safe.
If you want to check malware, phisinng, ... you're free to do it.
No, it uses Webkit under the hood, which does not check for malwares, but it may give you only hints on expired certificates, self-signed certificates or invalid ones.
You should implement a request filter, which performs better SSL checks for valid certificates and uses some third-party anti-malware / dangerous domains and keep them out. In that case, you just ignore "that" request.

Passbook couldn't connect to development web service

I'm creating my own Passbook Web Service, in order to register and update passes created by my server. When I add to the Pass information inside the pass.json the webServiceURL and the authenticationToken attributes, the pass is displayed but not added to the iOS Passbook App. Given I'm still in development I don't have a https with SSL server, but a plain http one:
http://192.168.1.100:8080/PassbookDelivery
Does the device and/or the protocol inside the Web Service need some special change in order to accept the pass produced by my server? Does the authenticationToken have any restriction, like string length, cipher or content?
NOTE: I already use the format URL for registering the device for updates, as detailed in the Passbook web service specification, which is (POST)
http://192.168.1.100:8080/PassbookDelivery/v1/devices/_deviceLibraryIdentifier_/registrations/_passTypeIdentifier_/_serialNumber_
but it doesn't get any call from the device.
Try this: go to Settings > Developer, scroll down to PASSKIT TESTING and toggle "Allow HTTP Services".

JMeter - How can I use the proxy with secure mobile pages?

I'm using JMeter's proxy to record the HTTP traffic from a mobile app.
It works fine with non secure HTTP requests, but when I try to make a HTTPS request I get an error: "The certificate for this server is invalid" (see screenshot below).
This is of course expected. If I'm on a PC I can simply click on "accept bad certificate" (or something like that) but this isn't an option for my mobile app (I'm testing amazon's app for example).
Is there a way to get my iPhone (or other mobile device) to accept JMeter's certificate?
Is there another way to do this with a REAL mobile device?
edit:
Some of the answers talk about how to modify my app.
I can't modify the app myself - so I need a solution that doesn't require any app modification.
After some research I found this link:
http://nat.guyton.net/2012/01/20/adding-trusted-root-certificate-authorities-to-ios-ipad-iphone/
Which almost works :)
The comments say that in iOS 6 and up using a MD5 doesn't work, and the default key JMeter is using is MD5.
Any thoughts?
Update Feb 13, 2014:
I had given up on this originally, but recently came across an article about using Charles proxy with a real device to capture SSL traffic by adding a certificate to your iPhone. After following the instructions here it works!
http://www.charlesproxy.com/documentation/faqs/ssl-connections-from-within-iphone-applications/
So now I know a solution IS possible, but I'm still stuck on how to get it to work - now using JMeter 2.11 and iOS 7
Thanks
Ophir
These related questions may be helpful:
iphone: secure restfull server "The certificate for this server is invalid
HTTPS Service is not working
HTTPS post request in IOS
I just happened to write an article on that given the new restrictions on iOS 13. In a nutshell:
Generate a certificate.
Import it into your proxy tool (I used OWASP ZAP).
Import the certificate into iOS and add it as a trusted authority.
Access iOS’ proxy settings and point it to your computer.
Full details in the article link below. Hope you find it helpful.
Best regards,
Andre
https://link.medium.com/gcU2SYZtn4

Implicitly trust SSL certificates in iOS app for private API

I'm working on an iOS app with a rails backend, running on a VPS (via my own domain).
My question is: is it insecure to use a self-signed SSL certificate on my server and ignore the warnings from NSURLConnection while communicating with it, considering that this is a private API which is only accessible via my iOS app?
The safe way to go in this scenario is: Sign it yourself and manually add the certificate to the local certificate database of every system you work from, so you don't need authentication to know it's yours. Sometimes this can be done automatically as easily as checking the box "ignore the warning for this certificate" the first time you connect from each system, which will prevent you from seen it again on that system unless the certificate changes.
This way you won't see the warning again, unless it's somebody else's self certificate you're looking at.
Ignoring the warning by default usually means that if somebody else signs its own certificate and presents it to you, you will go along without even noticing. Not a good idea.

Resources