0 votes
by (120 points)

Hi,
I downloaded RebexHttps-2017R2-Trial.exe to support TLS 1.2 in .net CF 3.5.
I did the adjustment but cannot log into https sites. My code is given bellow.

This was an existing code and i modified it to support TLS 1.2 based on the instructions given in Rebex site. But i feel i have missed something.

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Rebex.Net;
using Rebex.Security;


namespace myTest.WebService
{
    public partial class DATA_CAPTURE_MANAGEMENT : System.Web.Services.Protocols.SoapHttpClientProtocol
    {
        protected override System.Net.WebRequest GetWebRequest(Uri uri)
        {
            HttpRequestCreator creator;

            creator = new Rebex.Net.HttpRequestCreator();
            creator.Register();
            //creator.Settings.SslAllowedVersions = TlsVersion.TLS12 | TlsVersion.TLS11 | TlsVersion.TLS10;
            System.Net.WebRequest request = base.GetWebRequest(uri); 
            switch (uri.Scheme)
            {
                case "http":
                    request = creator.Create(uri);
                    break;
                case "https":
                    // use Rebex HttpRequest to handle HTTP and HTTPS requests
                    request = creator.Create(uri);
                    break;
                default:
                    // use default functionality to handle other requests
                    request = base.GetWebRequest(uri);
                    break;
            }

            if (PreAuthenticate)
            {
                System.Net.NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic");
                request.Credentials = Credentials.GetCredential(uri, "Basic");
                if (networkCredentials != null)
                {
                    byte[] credentialBuffer = new System.Text.UTF8Encoding().GetBytes(
                    networkCredentials.UserName + ":" + networkCredentials.Password);
                    request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(credentialBuffer));
                }
                else
                {
                    throw new ApplicationException("No network credentials");
                }
            }
            if (myTest.Helpers.Configuration.CurrentCultureName != null)
            {
                request.Headers.Add("ACCEPT-LANGUAGE", myTest.Helpers.Configuration.CurrentCultureName);
            }  
            return request;
        }
    }
}
Applies to: Rebex HTTPS

1 Answer

+1 vote
by (73.6k points)

Hello,

your code should work as expected if:

  1. The PreAuthenticate is set to true - In my test project I realized that the PreAuthenticate is always false.

  2. The Credentials property contains required credentials - In my test project I realized that the Credentials is always null.

Please ensure that line request.Headers.Add("Authorization", ... was executed.

I suggest you to use one particular credential and if it works, then use Credentials.GetCredential() logic.

I also suggest you to do it like this:

request.Credentials = new NetworkCredential(username, password);

This will enables you to use other authentication mechanisms such as Negotiate or Ntlm automatically. However setting Authorization header explicitly works as well.

And the last comment of your code:
You can use either creator.Register(); or creator.Create(uri); Using both together has no meaning. Please note that when you execute creator.Register(); all subsequent creations of WebRequest class will create instances of Rebex HttpRequest (not only in DATA_CAPTURE_MANAGEMENT class, but everywhere in project).

So use it like this:

creator = new Rebex.Net.HttpRequestCreator();
creator.Register();
System.Net.WebRequest request = base.GetWebRequest(uri); 

or like this:

creator = new Rebex.Net.HttpRequestCreator();
System.Net.WebRequest request;
switch (uri.Scheme)
{
    case "http":
    case "https":
        // use Rebex HttpRequest to handle HTTP and HTTPS requests
        request = creator.Create(uri);
        break;
    default:
        // use default functionality to handle other requests
        request = base.GetWebRequest(uri);
        break;
}
by (120 points)
Hi Lukas,
Thank you for the reply.
PreAuthenticate is already set to true before executing the logic. And I set the credentials explicitly.
`request.Headers.Add("Authorization’ code part also get executed.

The exception I get here is
 _innerException    {"Server certificate was rejected by the verifier because of an unknown certificate authority."}    System.Exception {Rebex.Net.TlsException}.
This is only for HTTPS sites.
Is there anything to do with certificates?
We have already set
ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();

Regards,
Ruwani.
by (73.6k points)
Oh, I thought you cannot authenticate (you wrote "cannot log into https sites"). But this error has nothing to do with client authentication.

This exception says, that your computer doesn't trust server's certificate (client failed to validate server's certificate).

The "because of an unknown certificate authority" means, that the root certificate which issued the server's certificate is not trusted by your computer. To solve this, you have 2 choices:

1. add the root certificate into your Certificate Store under Trusted Root Certificates.
2. ignore or validate the certificate different way. To see how to do this please visit http://www.rebex.net/https/features/tls-ssl.aspx

To know more about "Server certificate was rejected ..." problems please visit http://blog.rebex.net/howto-server-certificate-rejected-exception/
by (120 points)
Hi Lukas,
I have set
creator.Settings.SslAcceptAllCertificates = true;
It worked well. Thank you very much.
But I have a small doubt. Will it affect the security of my mobile application if I set this property to true?
by (148k points)
We commented on this in the blog post with these words: "Doing this in production environment is highly discouraged, as it effectively disables server authentication."

However, that was in 2012. Today, our recommendation for most scenarios is even stronger: "NEVER use 'SslAcceptAllCertificates=true' in production! Doing so enables man-in-the-middle attacks and essentially renders TLS/SSL completely useless."

The property is useful when testing or debugging because it makes it possible to determine whether the application would work if certificate validation succeeded, but don't use it in production environments unless the connection between to the client and server is sufficiently secure even without TLS/SSL. In other words, only enable SslAcceptAllCertificates if not using TLS/SSL at all would be acceptable as well.
by (120 points)
Hi Lukas,
Thank you. I will try the other options you have suggested.

Regards,
Ruwani
...