Welcome Guest Search | Active Topics | Sign In | Register

NeedClientCertificate, HandleLoadFailed: Error code:-117 Options
JOERIDDM
Posted: Tuesday, June 20, 2017 11:41:22 AM
Rank: Newbie
Groups: Member

Joined: 6/20/2017
Posts: 8
Hi Everyone,

One of our clients requires the ability to connect to a website which uses a smartcard with a pincode for authentication. When I connect the smartcard to my computer, the certificate on the card will be stored inside the Windows certificate store, from where I fetch the certificate in c#. When the certificate is later used for authentication, Windows will automatically ask for the pincode.

When using Google Chrome

When using Google Chrome, the browser will display a popup from which I can choose a certificate (see figure 1).
After choosing the certificate Windows will display a window where I will be asked for the pincode of my smartcard (see figure 2).
After filling in my pincode and pressing ok I will be authenticated.

Figure1:

In case the image is not displaying: figure1

Figure2:

In case the image is not displaying: figure2

When using EO webbrowser

When using EO webbrowser no popup is showed where I can choose the certificate from. A NeedClientCertificate is fired instead, which I try to handle as following:

(Some of it is pretty much hard coded, but I'm planning to fix this later.
I x'ed out the real value for the serialNumber variable on purpose aswel.)

- Fetch the certificate from the Windows certificate store
- Choose the right certificate from the certificate collection
- Pass the certificate to the Continue method

Code: C#
//fetch certificates from the Windows certificate store
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection coll = store.Certificates;

            //Look for the right certificate
            X509Certificate2 cert = null;
            foreach (X509Certificate2 c in coll) {
                String serialNumber = "XXXX";
                if (c.SerialNumber.Equals(serialNumber)) 
                {
                    cert = c;
                    break;
                }
                String name = c.Subject;
                String name2 = c.FriendlyName;
                Console.WriteLine(name + " " + name2);

            }

            //pass the certificate as parameter to the Continue method
            e.Continue(cert);


After doing this Windows will ask for my pincode again the same way as when using a normal Google Chrome browser (figure 2).
The problem is that this will fire a LoadFailed event. No CertificateError event is fired however.

The LoadFailedEventArgs always contains the following details:

Url: null
ErrorMessage:Error code:-117
ErrorCode:-117
HttpStatusCode: 0

I know I did not provide you with a lot of details on the certificate itself so far. This is because the certificate is highly personal. In case there are any more questions regarding the certificate, please feel free to ask and I will provide the information if possible.

Thanks for your help!

Kind regards,
Joeri
eo_support
Posted: Tuesday, June 20, 2017 4:44:24 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,071
Hi,

Error code -117 means "BAD_SSL_CLIENT_AUTH_CERT". This can be caused by AntiVirus program that incorrectly intercepts HTTPS traffic. Here is one post regarding this:

https://stackoverflow.com/questions/36309562/err-bad-ssl-client-auth-cert

If that's not the problem, please check whether the X509Certificate2 object you pass to Continue has private key information. Your X509Certificate2 must contains private key information because the private key is needed to encrypt the information on the senders end. We are not particular familiar with reading certificate from a smartcard, here is a post that you might find useful:

https://stackoverflow.com/questions/22236116/find-certificate-on-smartcard-currently-on-reader

Please let us know if this resolves the issue for you.

Thanks!
JOERIDDM
Posted: Wednesday, June 21, 2017 4:08:52 AM
Rank: Newbie
Groups: Member

Joined: 6/20/2017
Posts: 8
Hi,

Thanks for your reply.
Unfortunately I was not able to solve the problem yet.
The type of smartcard I'm using is a Belgian identity card.
It can be used to log in on a few government related websites.
The previous browser library we were using has no problems handling this tough.
We eventually decided to switch to EO because the previous library had some stability issues.
Therefore I assume it is not the firewall.
I'm afraid that the second link doesn't really help either.

EDIT: more info on these cards:http://repository.eid.belgium.be/index.php?lang=en


Kind regards,
Joeri
JOERIDDM
Posted: Wednesday, June 21, 2017 10:18:06 AM
Rank: Newbie
Groups: Member

Joined: 6/20/2017
Posts: 8
This does not have anything to do with EO webbrowser, but when I do a test with the following code, everything seems to work fine.
So I guess there must be something in the EO.WebBrowser.NeedClientCertificateEventArgs.Continue method that causes the problem.

Code: C#
using System;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Security;

namespace Browserlesstest
{
    class Program
    {
        static Boolean quit = false;
        static void Main(string[] args)
        {
            Console.WriteLine("hi");
            SendRequestUsingHttpClient();
            while (!quit) ;
            Console.WriteLine("Press any key to stop...");
            Console.ReadKey();
        }
        private static async Task SendRequestUsingHttpClient() {
            WebRequestHandler handler = new WebRequestHandler();
            X509Certificate certificate = GetCert();
            handler.ClientCertificates.Add(certificate);
            //handler.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
            //handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            
            using (var client = new HttpClient(handler))
            {
                client.BaseAddress = new Uri("https://test.eid.belgium.be/");
                client.DefaultRequestHeaders.Accept.Clear();
                HttpResponseMessage response = await client.GetAsync("");
                if (response.IsSuccessStatusCode)
                {
                    string content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine("Received response: {0}", content);
                }
                else
                {
                    Console.WriteLine("Error, received status code {0}: {1}", response.StatusCode, response.ReasonPhrase);
                }
            }
            quit = true;
        }

        private static X509Certificate GetCert()
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection coll = store.Certificates;

            X509Certificate2 cert = null;
            //return coll[4];
            foreach (X509Certificate2 c in coll)
            {
                String serialnumber = "XXXXX";
                if (c.SerialNumber.Equals(serialnumber))
                {
                    cert = c;
                    break;
                }
            }

            return cert;
        }
   }
}
eo_support
Posted: Wednesday, June 21, 2017 12:55:40 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,071
Hi,

This has to do with how EO.WebBrowser pass the certificate to the browser engine. When you open a certificate store in your code, there is a "handle" in your process that represents the specific certificate. As long as all code using this handle, everything will work fine.

EO.WebBrowser can not pass that handle directly because the browser engine code actually runs inside a separate process. So it must pass the raw certificate date. This raw certificate data must contain private key in order for it to work since private key is needed for encryption.

We are currently looking into adding an option for you to fall back to the "default" behavior where the browser process will display the select certificate UI thus maintain the handle inside the browser process. In theory this should work for your case. However we do not have a smart card test environment to verify. The final syntax will be something like this:

Code: C#
//This code continues with your certificate. The certificate
//must have private key
e.Continue(your_certifcate);

//This code continues without any certificate. The connection
//will fail if the server requires a certificate
e.ContinueWithoutCertificate();

//This code displays the OS's Select Certificate dialog to select
//a certificate
e.Continue();


We will reply again when we have an update on this.

Thanks!
JOERIDDM
Posted: Thursday, June 22, 2017 4:08:37 AM
Rank: Newbie
Groups: Member

Joined: 6/20/2017
Posts: 8
Hi,

Thanks for the support!

I do not want to look impatient, but we actually need a solution to this problem quite urgently.
Have you got any idea when I can expect this option to become available?
I understand you do not have the necessary equipment to verify the solution.
I'll let you know whether it works or not after its release.

Kind regards,
Joeri
eo_support
Posted: Thursday, June 22, 2017 8:22:16 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,071
Hi,

We will try to implement this in the next two weeks. If we can have it sooner, we will let you know as soon as the new build is ready.

Thanks!
eo_support
Posted: Friday, June 30, 2017 4:23:30 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,071
Hi,

This is just to let you know that we have posted a new build that MAY resolve this issue for you. You do not need to change your code. Your code will still be:

e.Continue(your_certificate);

This certificate must be from your "My" certificate store for the current user that supports client authentication. In another word, if you load the same page with Google Chrome and Google Chrome prompts you to choose from a list of certificates, the certificate you pass to us must exists in that list. In this case we will "re-open" the same certificate in the browser engine process and the whole process should work the same as in-process implementations.

You can download the new build from our download page. Please take a look and let us know if it works for you.

Thanks!
JOERIDDM
Posted: Monday, July 3, 2017 4:27:32 AM
Rank: Newbie
Groups: Member

Joined: 6/20/2017
Posts: 8
Hi,

At a first glance it all seems to be working now.
I'll let you guys know should I run into other problems regarding this issue,
but for now it all seems to be working just fine. :)

Thanks a lot for the effort and the quick response!
Keep up the good work!

Kind regards,
Joeri
eo_support
Posted: Monday, July 3, 2017 9:38:21 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,071
Glad to hear that! Please feel free to let us know if you see any other problems.


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.