2

I've managed to use client certificates successfully with the .Net HttpWebRequest class but I'm now trying to update ModernHttpClient to support Client Certificates so it's using the more efficient iOS libraries for requests.

I've modified the DidReceiveChallenge function in NSUrlSessionHandler to check for ClientCertificate challenges and attempted to follow through the information on https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/AuthenticationChallenges.html and convert it to work with Xamarin iOS. The code compiles correctly and stepping through it causes no errors to be printed out but ultimately I still get a System.Net.WebException thrown with the message 'The server "xxx.example.com" requires a client certificate'.

My code is below...

public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) { ...snip... if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodClientCertificate) { Console.WriteLine("Client Cert!"); var password = "xxxxx"; var options = NSDictionary.FromObjectAndKey(NSObject.FromObject(password), SecImportExport.Passphrase); var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Content", "client.p12"); var certData = File.ReadAllBytes(path); NSDictionary[] importResult; X509Certificate cert = new X509Certificate(certData, password); SecStatusCode statusCode = SecImportExport.ImportPkcs12(certData, options, out importResult); var identityHandle = importResult[0][SecImportExport.Identity]; var identity = new SecIdentity(identityHandle.ClassHandle); var certificate = new SecCertificate(cert.GetRawCertData()); SecCertificate[] certificates = { certificate }; NSUrlCredential credential = NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); return; } ...snip... } 

I've committed my changes so far to GitHub if you want to trial it out (https://github.com/MrsKensington/ModernHttpClient). BTW, the test client certificate secured web server has absolutely nothing of any value on it (only one .txt file) and the certificate and password is unique to this web server, so I have no qualms with sharing this with the world.

Thanks in advance for any help,

Mrs Kensington

1
  • Very good question @Mrs, can you give me some help about the following: 1. How do I generate the P12 file from IIS? can it be .pfx or .cer? Commented May 16, 2017 at 19:17

1 Answer 1

2

Shouldn't you use the handle instead of the classhandle ?

var identity = new SecIdentity(identityHandle.Handle); 

Have you made any progress so far? I need similar code for a WkWebView app.

Sign up to request clarification or add additional context in comments.

1 Comment

Good spot! I changed to use the Handle property and it worked perfectly! I've updated my code on GitHub with the change in case anyone else needs it. Unfortunately I know nothing about WkWebView so can't help you on that but thanks so much for the help!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.