Bug 7530 - Webservice ClientCertificate mechanism broken for iOS 4.x in MT 6.0
Summary: Webservice ClientCertificate mechanism broken for iOS 4.x in MT 6.0
Status: RESOLVED NORESPONSE
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 6.0.x
Hardware: Other Other
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-09-28 11:17 UTC by Chris Hatton
Modified: 2013-12-05 18:35 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NORESPONSE

Description Chris Hatton 2012-09-28 11:17:39 UTC
Hello,

After installing MT 6.0, our App which uses web-services over HTTPS can no longer communicate to the server on devices running iOS 4.x. Later versions, iOS 5.x and 6.0 are unaffected.

While the older versions may be less important now, this is still a clear regression that may point to a wider issue, and ideally we would like to support 4.x for our clients.

I isolated this issue with the code which follows; calling one of our Logging web-services, and the issue is manifest. Unfortunately I cannot give you the fully working fragment as it includes our X509 certificate.

The issue may be that the X509 cert is not correctly added to the service, or applied at invocation time.
On 6.0 and 5.x devices, the call executes and the ending dialog is displayed.
On 4.x we get:

System.Net.WebException: Error writing request: The authentication or decryption has failed.
  at System.Net.WebConnectionStream.WriteHeaders () [0x00050] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebConnectionStream.cs:680
  at System.Net.WebConnectionStream.SetHeaders (System.Byte[] buffer) [0x00083] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebConnectionStream.cs:648
  at System.Net.HttpWebRequest.SendRequestHeaders (Boolean propagate_error) [0x0010c] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1158

Thanks for giving this issue your consideration, and please do get in touch if you require any further information.

Regards,
Chris

Example code follows:
-------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;

using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Security.Cryptography.X509Certificates;

using iPhoneClient.Usage;
using HTTPS_Test.LogRecorder;

namespace HTTPS_Test
{
	[Register ("AppDelegate")]
	public partial class AppDelegate : UIApplicationDelegate
	{
		UIWindow window;

		public override bool FinishedLaunching (UIApplication app, NSDictionary options)
		{
			window = new UIWindow (UIScreen.MainScreen.Bounds);
			window.MakeKeyAndVisible ();

			string url = "<secret test URL>/LogRecorder2.svc";

			var service = new LogRecorder.LogRecorder2 (url);

			service.Timeout = 120000;

			byte[] cert = System.Convert.FromBase64String("<secret X509 cert>");
			service.ClientCertificates.Add(new X509Certificate2(cert, "password1", X509KeyStorageFlags.PersistKeySet));

			var testEvent = new ClientUsageEvent()
			{
				<secret but unimportant event parameters>
			};

			service.UploadRecords (testEvent);
		
			window.RootViewController = new UIViewController();

			var alert = new UIAlertView("","Test log event posted",null,"Ok",null);
			alert.Show();

			return true;
		}
	}
}
Comment 1 Sebastien Pouliot 2012-09-28 11:59:33 UTC
The MonoTouch *code* should be independent of the iOS version being used.

However MonoTouch delegates the X.509 certificate checks to iOS, so it's possible that some certificates are "trusted" only by more recent versions of iOS (which would have more recent trust roots).

Have you tried to override the certificate validation ?

What specific version of iOS 4.x are you using ?
Comment 2 Chris Hatton 2012-09-28 12:44:06 UTC
We are experiencing the same with two devices, one on 4.3.1 and the other on 4.3.3.

This was not an issue on the same devices, when the build was performed with MT <6.0.

I successfully overrode certificate validation with:

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback( ValidateRemoteCertificate );

private static bool ValidateRemoteCertificate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors )
		{
			return true;
		}

This does allow the service call to be made, so you are right about it refusing the certificate.
During the ValidateRemoteCertificate call, policyErrors is 'RemoteCertificateChainErrors'.

I will continue drilling and investigating, strange thing is that the same combination of iOS / Device / Source code didn't fail on earlier builds before MT 6.0.  Is there anything about the produced executable that would give it access to different root certs etc.?
Comment 3 Sebastien Pouliot 2012-09-28 13:17:32 UTC
Do you recall which version of MT was working ?

There was a bug (a few versions back) that could have allowed this certificate to be accepted (even if iOS itself did not like it).
Comment 4 Chris Hatton 2012-10-01 09:19:42 UTC
It was working right up until 6.0, since a long time back ~18 months of staying up-to-date with the latest MT releases.

Some further info: the X509 certificate that is receiving the RemoteCertificateChainErrors on 4.x is from issuer www.digicert.com who are a confirmed trusted certificate provider since iOS 3.1.

CN=*.ie.com, OU=Mobile, O=Intelligent Environments Europe Limited, L=Kingston Upon Thames, S=Surrey, C=GB

[Issuer]
CN=DigiCert High Assurance CA-3, OU=www.digicert.com, O=DigiCert Inc, C=US

http://support.apple.com/kb/HT3580

We need to support this iOS version for our clients, and due to the secure nature of our application, force-accepting the SSL certificate is not an option, so would greatly appreciate any assistance you can give to help resolve this issue.

I really want to get a confirmed positive result on this test project, on an iOS 4.x device, compiled with the MT 5.4.1 toolchain. But unfortunately all our machines are now upgraded to the 6.0 toolchain. I have a spare machine and the 5.4.1 pro installer, but cannot activate it due to licensing issues so I am being blocked from doing a fair test.

Can you offer any advice for how to test this, or nudge the activation counter for my license key (I can PM it to you) so that I can activate on the spare machine for testing purposes? Thanks.
Comment 5 Chris Hatton 2012-10-01 09:33:14 UTC
I noticed that in 6.0.2 there have been a slew of bug-fixes to WebServices + HTTP stacks, which is very close to this area. Could this be related to those issues? I have updated to 6.0.2 but are still experiencing this issue.
Comment 6 Sebastien Pouliot 2012-10-01 09:46:40 UTC
You'll need to contact support for activations (I can't do that). 

OTOH you should be able to rename your /Developer/MonoTouch directory to something else (e.g. /Developer/MonoTouch6) and install an earlier (like 5.4.1) release. You can then use the SDK location (from MonoDevelop) to switch back and forth the two versions.

"CN=DigiCert High Assurance CA-3, OU=www.digicert.com, O=DigiCert Inc, C=US" is not part of the list (from Apple's KB) but that's likely because it's not a root CA (just an intermediate CA). However that does not tell who has signing this CA (but since newer iOS releases have the same DigiCert roots this is unlikely to be the problem).

note: 6.0.2 has several networking fixes but none regarding how SSL/TLS/Certificate validation is being done.
Comment 7 PJ 2013-11-19 17:05:00 UTC
This bug has been in the NEEDINFO state with no changes for the last 90 days. Can we put this back into the NEW or CONFIRMED state, or are we still awaiting response?

If there is no change in the status of this bug over the next two weeks, this bug will be marked as NORESPONSE.
Comment 8 PJ 2013-12-05 18:35:20 UTC
This bug has not been changed from the NEEDINFO state since my previous comment, marking as RESOLVED NORESPONSE.

Please feel free to REOPEN this bug at any time if you are still experiencing the issue. Please add the requested information and set the bug back to the NEW (or CONFIRMED) state.